深刻理解Javascript protype html
JavaScript并非一种面向对象的程序设计语言,严格来说,它并无什么类的概念,顶多只是JSON对象而已,然而在JavaScript中有prototype这个关键字,利用它,咱们能够间接地实现一些面向对象的特性。 浏览器
1
2
3
4
5
6
7
8
9
10
|
varUser =function() {
this.username ='username';
this.password ='password';
this.toString =function() {
returnthis.username +':'+this.password;
}
}
varuser =newUser();
document.write(user +'<br />');
|
这是一个很简单的封装实现,此时的User能够被视为一个“类”,这里还有一个方法叫作toString,实际上,在须要字符串的地方,对象的toString方法会自动被调用。 函数
若是在上面这个例子中,toString没有被定义在User里面,也能够经过prototype关键字来定义在外部,效果是等价的。 post
1
2
3
|
User.prototype.toString =function() {
returnthis.username +':'+this.password;
};
|
若是在这个例子中没有写prototype关键字,那么user对象其实是没有toString这个函数能够调用的,由于没有prototype表明这个toString函数仅被定义在User自己之上。 this
这是什么原理呢? spa
首先,使用new关键字进行新对象user的构造时,是调用了上面赋值给User的匿名函数,这个函数赋予了新对象user一些属性,就像在函数体中所写的那样。若是toString没有被定义在里面,那么此时user只有username和password两个属性。 prototype
若是在外部定义的toString没有加上prototype关键字,那么会发生什么状况呢?User对象具备了toString方法,然而User自己却没有username和password。所以,此时User的username与password均为undefined,有没有以为比较像面向对象语言中的静态方法呢?是的,相同点在于:咱们能够经过“类名”直接调用该方法,该方法不能使用“非静态”成员。 设计
若是在toString被定义在User.prototype之下,user对象就会具备toString方法,这是为何呢?由于每一个对象都隐含了一个名为__proto__的属性,至关于在User构造函数的最后增长了: htm
1
|
this.__proto__ = User.prototype;//注意,这个__proto__是内部名称,不一样浏览器实现不一样名称也可能不相同。
|
prototype这个特殊的属性在构造函数定义时被初始化,初始化时包含了User的构造函数自己和本身的__proto__属性,当用户经过User.prototype的方式定义新属性或方法的时候,这些属性或方法就被增长到User.prototype这个JSON对象之中。因为this.__proto__ = User.prototype;的缘故,调用这个构造函数构造的全部对象的__proto__属性中,都包含有这个新属性或方法。所以,实际上toString并无成为user下的一个方法,而是user.__proto__下的一个方法。 对象
而后,实际执行user.toString()时,浏览器将检查user是否具备toString方法能够调用,若是没有,浏览器将继续检查其__proto__属性中是否有toString方法,若是仍然没有,则继续递归向上寻找这个__proto__属性的__proto__属性。如此,就能够解释为何prototype下定义的方法,均可以被该“类”的全部实例调用的缘由了。