??JS里万物皆对象,对象又分为普通对象和函数对象。每当定义一个对象时,对象中都会包含一些预定义的属性。其中每个对象都有一个_proto_属性,这个属性用来指向创建它的构造函数的原型对象;每个函数对象都有一个prototype 属性,这个属性指向的是该函数的原型对象。
? 先说一下函数对象的prototype属性
function f(){}
f.prototype = { name: 'myfriend '};//f的原型对象
var a = new f();
var b = new f();
a.name //myfriend
b.name //myfriend
??原型对象可以实现类似继承的机制和完成数据的共享。所有实例对象需要共享的属性和方法,都放在这个原型对象里面;那些不需要共享的属性和方法,就放在构造函数里面。
//接着上面的代码
f.prototype.name = 'hello';
a.name //hello
b.name //hello
??原型对象的属性不是实例对象自身的属性。当实例对象本身没有某个属性或方法的时候,它会到原型对象去寻找该属性或方法。这就是原型对象的特殊之处。如果实例对象自身就有某个属性或方法,它就不会再去原型对象寻找这个属性或方法。
a.name = "luse"
a.name // 'luse'
b.name // 'hello'
f.prototype.name // 'hello';
其次是所有对象都有_proto_,指向的是其构造函数的原型对象。
//接着上面的代码
a._proto_ == f.prototype // true
b._proto_ == f.prototype // true
??现在再来看一下什么是原型链,所有对象的原型最终都可以上溯到Object.prototype,这就是所有对象都有valueIf和toString方法的原因,因为这是从Object.prototype继承的。
//接着上面的代码
// a是一个对象,又_proto_属性,指向a的构造函数的原型对象
a._proto_ == f.prototype
// f.prototype是一个对象,也会有_proto_属性,指向f的构造函数的原型对象
f.prototype._proto_ == Function.prototype
// Function.prototype是一个普通对象,也会有_proto_属性,指向Function.prototype的构造函数的原型对象
Function.prototype._proto_ == Object.prototype
//直到原型链的最顶端为null,整个为一个链形结构
Object.prototype._proto_ == null