我很好奇以下OOP javascript技术之间的区别.他们似乎最终做了同样的事情但被认为比另一个更好?
function Book(title) {
this.title = title;
}
Book.prototype.getTitle = function () {
return this.title;
};
var myBook = new Book('War and Peace');
alert(myBook.getTitle())
Run Code Online (Sandbox Code Playgroud)
VS
function Book(title) {
var book = {
title: title
};
book.getTitle = function () {
return this.title;
};
return book;
}
var myBook = Book('War and Peace');
alert(myBook.getTitle())
Run Code Online (Sandbox Code Playgroud)
rek*_*o_t 46
第二个并不真正创建一个实例,它只返回一个对象.这意味着你不能利用像这样的运营商instanceof
.例如.在第一种情况下,您可以if (myBook instanceof Book)
检查变量是否是Book的类型,而在第二个示例中,这将失败.
如果要在构造函数中指定对象方法,这是执行此操作的正确方法:
function Book(title) {
this.title = title;
this.getTitle = function () {
return this.title;
};
}
var myBook = new Book('War and Peace');
alert(myBook.getTitle())
Run Code Online (Sandbox Code Playgroud)
虽然在这个例子中两者的行为方式完全相同,但存在差异.使用基于闭包的实现,您可以拥有私有变量和方法(只是不要在this
对象中公开它们).所以你可以做一些事情,比如:
function Book(title) {
var title_;
this.getTitle = function() {
return title_;
};
this.setTitle = function(title) {
title_ = title;
};
// should use the setter in case it does something else than just assign
this.setTitle(title);
}
Run Code Online (Sandbox Code Playgroud)
Book函数之外的代码不能直接访问成员变量,它们必须使用访问器.
其他最大的不同是表现; 由于使用闭包包含一些开销,基于原型的分类通常要快得多.您可以在本文中了解性能差异:http://blogs.msdn.com/b/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx
小智 12
哪个更好有时可以通过其使用的上下文来定义.
我如何在Prototype和Closure编码方法之间做出选择的三个约束条件(我主动使用两者):
1.业绩/资源
对于对象的单个实例,任何一种方法都可以.任何速度优势都很可能是微不足道的.
如果我实例化其中的100,000个,比如建立一个图书馆,那么原型方法将是首选.所有.prototype.函数只会被创建一次,而不是使用闭包方法创建100,000次这些函数.资源不是无限的.
2.压缩
如果压缩效率很重要,请使用Closure方法(例如:大多数浏览器库/模块).请参阅以下说明:
压缩 - 原型方法
function Book(title) {
this.title = title;
}
Book.prototype.getTitle = function () {
return this.title;
};
Run Code Online (Sandbox Code Playgroud)
是YUI压缩到
function Book(a){this.title=a}Book.prototype.getTitle=function(){return this.title};
Run Code Online (Sandbox Code Playgroud)
节省约18%(所有空格/标签/退货).此方法需要公开变量/函数(this.variable = value),因此每个原型函数都可以访问它们.因此,这些变量/函数不能在压缩中进行优化.
压缩 - 闭包方法
function Book(title) {
var title = title; // use var instead of this.title to make this a local variable
this.getTitle = function () {
return title;
};
}
Run Code Online (Sandbox Code Playgroud)
是YUI压缩到
function Book(a){var a=a;this.getTitle=function(){return a}};
Run Code Online (Sandbox Code Playgroud)
节省约33%.可以优化局部变量.在具有许多支持功能的大型模块中,这可以显着节省压缩.
3.项目管理
在一个有多个开发人员的项目中,他们可能在同一个模块上工作,我更喜欢该模块的原型方法,如果不受性能或压缩的限制.
对于浏览器开发,我可以覆盖我自己的"test.js"中的"production.js"中的producton.prototype.aFunction(在后面读到),以便进行测试或开发,而无需修改"production.js" ,可能由不同的开发人员积极开发.
我不是复杂的GIT存储库检出/分支/合并/冲突流的忠实粉丝.我更喜欢简单.
此外,通过测试平台重新定义或"劫持"模块功能的能力可能是有益的,但这里要解决的问题太复杂了......
Ski*_*ick 11
前一种方法是如何使用JavaScript.后者是更现代的技术,部分由Douglas Crockford推广.这种技术更灵活.
你也可以这样做:
function Book(title) {
return {
getTitle: function () {
return title;
}
}
}
Run Code Online (Sandbox Code Playgroud)
返回的对象只有一个被调用的访问器getTitle
,它将返回在闭包中保存的参数.
Crockford 在JavaScript中有一个很好的私人会员页面- 绝对值得一读,看看不同的选项.
这也是关于引擎盖下的可重用性的一点点.在具有Function.prototype
属性用法的第一个示例中,Book函数对象的所有实例将共享该getTitle
方法的相同副本.而第二个片段将使Book
函数执行创建并保留在堆"书架"中的本地可关闭 book
对象的不同副本.
function Book(title) {
var book = {
title: title
};
book.getTitle = function () {
return this.title += '#';
};
return book;
}
var myBook = Book('War and Peace');
var myAnotherBook = Book('Anna Karenina');
alert(myBook.getTitle()); // War and Peace#
alert(myBook.getTitle()); // War and Peace##
alert(myAnotherBook.getTitle()); // Anna Karenina#
alert(myBook.getTitle());// War and Peace###
Run Code Online (Sandbox Code Playgroud)
new
另一方面,原型成员存在于对象的所有实例的唯一副本中.所以这是他们之间的一个更微妙的区别,由于封闭技巧,第一次叹息不是很明显.
归档时间: |
|
查看次数: |
25079 次 |
最近记录: |