我真的不懂JS的面向对象

我在写vools.js的时候,发现我写的对象继承的方式有点怪。后来去查阅了一下资料,还真的是这样。

今天下午写js的时候,写到这里发现了有点不对劲:


var UI = function (){}; UI.prototype = VoolsEvent.prototype;

如果是玩多重继承的话,那这个岂不是有问题?


var 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的实例并没有 iAmBiAmC 属性。因为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里可不是上面那样的:

function 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代码了


  1. 之前写错的地方。。。也得改过来orzorzorz ↩︎