第一个区别可以总结为:this
引用类的实例。prototype
参考定义。
假设我们有以下课程:
var Flight = function ( number ) { this.number = number; };
所以在这里,我们将附加this.number
到类的每个实例上,这是有道理的,因为每个实例都Flight
应该有自己的航班号。
var flightOne = new Flight( "ABC" );
var flightTwo = new Flight( "XYZ" );
相反,prototype
定义一个可以被所有实例访问的属性。
现在,如果要获取航班号,我们只需编写以下代码段,我们所有的实例都将获得对该新原型对象的引用。
Flight.prototype.getNumber = function () { return this.number; };
第二点区别在于JavaScript搜索对象属性的方式。当您寻找时Object.whatever
,JavaScript会一直到达主要的Object对象(其他所有对象都继承自该对象),并且一旦找到匹配项,它将立即返回或调用它。
但这仅适用于原型属性。因此,如果您位于较高的层中this.whatever
,则JavaScript不会将其视为匹配项,而是会继续搜索。
让我们看看它在现实中是如何发生的。
首先请注意,几乎所有内容都是JavaScript 中的对象。尝试这个:
typeof null
现在,让我们看看其中的内容Object
(注意大写字母O
和.
最后一个字母)。在Google Chrome开发人员工具中,输入时,.
您将获得该特定对象内可用属性的列表。
Object.
现在对以下内容执行相同的操作Function
:
Function.
您可能会注意到该name
方法。只需将其放火,然后看看会发生什么:
Object.name
Function.name
现在让我们创建一个函数:
var myFunc = function () {};
让我们看看是否在name
这里也有该方法:
myFunc.name
您应该得到一个空字符串,但这没关系。您不应收到错误或异常。
现在,让我们为类似神的东西添加一些东西Object
,看看是否也可以在其他地方得到它?
Object.prototype.test = "Okay!";
然后你去了:
Object.prototype.test
Function.prototype.test
myFunc.prototype.test
在所有情况下,您都应该看到"Okay!"
。
关于每种方法的优缺点,您可以将原型设计视为一种“更高效”的处理方式,因为它在每个实例上都保留一个引用,而不是在每个对象中复制整个属性。另一方面,这是紧密耦合的一个示例,在您不能真正说明理由之前,这是一个很大的禁忌。this
因为它与上下文有关,所以非常复杂。您可以在互联网上免费找到许多优质资源。
综上所述,这两种方法都只是语言工具,它确实取决于您和您要解决的问题,以选择更合适的方法。
如果您需要一个与类的每个实例相关的属性,请使用this
。如果您需要具有在每个实例上都具有相同功能的属性,请使用prototype
。
更新资料
关于样本片段,第一个是Singleton的示例,因此this
在对象体内使用是有意义的。您也可以通过使它像这样模块化来改进示例(并且您不必总是使用this
)。
/* Assuming it will run in a web browser */
(function (window) {
window.myApp = {
...
}
})( window );
/* And in other pages ... */
(function (myApp) {
myApp.Module = {
...
}
})( myApp );
/* And if you prefer Encapsulation */
(function (myApp) {
myApp.Module = {
"foo": "Foo",
"bar": function ( string ) {
return string;
},
return {
"foor": foo,
"bar": bar
}
}
})( myApp );
您的第二个片段没什么意义,因为首先您正在使用this
,然后尝试用它进行破解prototype
,这无效,因为this
优先级较高prototype
。我不确定您对那段代码有什么期望以及它的工作方式,但是我强烈建议您对其进行重构。
更新资料
为了详细说明this
优先顺序,prototype
我可以向您展示一个示例并告诉您如何进行解释,但是我没有任何外部资源可以对其进行备份。
这个例子很简单:
var myClass = function () { this.foo = "Foo"; };
myClass.prototype.foo = "nice try!";
myClass.prototype.bar = "Bar";
var obj = new myClass;
obj.foo; // Still contains "Foo" ...
obj.bar; // Contains "Bar" as expected
众所周知,这种解释this
与上下文有关。因此,直到上下文准备就绪,它才会存在。什么时候准备好上下文?创建新实例时!您现在应该猜剩下的!这意味着即使有一个prototype
定义,但this
优先还是要优先考虑,因为这全部与当时创建的新实例有关。