我在写vools.js的时候,发现我写的对象继承的方式有点怪。后来去查阅了一下资料,还真的是这样。
今天下午写js的时候,写到这里发现了有点不对劲:
12345var UI = function (){};UI.prototype = VoolsEvent.prototype;
如果是玩多重继承
的话,那这个岂不是有问题?
12345678910111213141516171819202122232425var A = function (){ this.constructPropertyA = 'AAA';};A.prototype.iAmA = 'i am A';var B = function (){ this.constructPropertyB = 'BBB';};B.prototype.iAmB = 'i am B';var C = function (){ this.constructPropertyC = 'CCC';};C.prototype.iAmC = 'i am C';B.prototype = A.prototype;C.prototype = B.prototype;for (var key in new C) { console.log(key);}// console output 'iAmA'
没错,构造函数C的实例并没有 iAmB
和 iAmC
属性。因为B声明了prototype属性后又把prototype换成A的prototype了(C也是一样)。所以只有iAmA
(大煞笔vec)
什么是原型链
JS当中实现继承的方式靠的是原型链(Prototype Chain)
的机制。类似于链子一样的结构
[A (constructPropertyA), {iAmA}]
↓
[B (constructPropertyB), {iAmB}]
↓
[C (constructPropertyC), {iAmC}]
new C;
/*
C {
constructPropertyC,
prototypeChain: B {
iAmB,
prototypeChain: A {
iAmA
}
}
}
*/
如果你想访问**C实例中的iAmA
**属性的话,JS首先会访问最高层的属性(就是constructPropertyC
那层),如果没找到iAmA
的话,则到prototypeChain
里继续搜索,直到最底层。
当然,JS里可不是上面那样的:
1234567891011121314151617181920212223242526272829303132function Animal(){}Animal.prototype.type = '哺乳动物';Animal.prototype.setAge = function (value){ this.age = value;};function People(){}People.prototype.setName = function (value){ this.name = value;};function Female(name, age){ this.setName(name); this.setAge(age);}Female.prototype.sex = '女';People.prototype.__proto__ = Animal.prototype;Female.prototype.__proto__ = People.prototype;var 妹子 = new Female('lily', 17);for (var key in 妹子) { console.info(key);}// console output 'name'// console output 'age'// console output 'sex'// console output 'setName'// console output 'type'// console output 'setAge'
终于实现了应该要有的效果了。。。然后我要继续写[1]代码了
之前写错的地方。。。也得改过来orzorzorz ↩︎