当我们声明一个构造器函数,并为其添加原型链方法的时候,我们会这样做:
function Super () {
...
}
Super.prototype.func = function () {
...
}
new 一个继承自super
的对象sub
并将其打印,会发现sub
上并没有prototype
,取而代之的是__proto__
,同时原型链上的func
方法也被挂载在了__proto__
属性上
那么构造器中的prototype
到哪里去了呢?这个莫名其妙就窃取了func
的__proto__
又是什么呢?
通过 proto 实现的“继承”
随意打印一个对象,会发现它们都有__proto__
属性,而__proto__
中也有__proto__
,一级一级追溯,会发现最终的__proto__
都是Object
其实,在 js 中并没有真正意义上的继承关系,通过new
实现的继承可以通过call
方式来实现
var sub1 = {}
sub1.__proto = Super.prototype
Super.call(sub1)
call
方式是将sub1
的__proto__
指向了Super
的prototype
,再改变执行环境,从而实现继承。那new
的对象的__proto__
是不是也等于Super
的prototype
呢?
var sub2 = new Super()
sub2.__proto__ === Super.prototype // true
当调用一个方法时,会先查询这个对象本身的属性,如果没有这个方法,再到它的__proto__
上查找,如果依然没有,就到__proto__
的__proto__
上查找,这样一级一级往上也就形成了原型链
综上所述(可能有点乱),对象的继承本质上通过__proto__
实现,而prototype
在整个原型链的实现中只是起到了一个辅助的作用
网友评论