javascript原型继承和对象属性

时间:2012-01-04 09:15:45

标签: javascript inheritance

我正在尝试将原型继承应用于Javascript中的函数。这一切都很简单,甚至在Wikipedia's javascript lemma中也有描述。如果我的属性是简单的javascript类型,它可以工作:

function Person() {
    this.age = 0;
    this.location = {
        x: 0,
        y: 0,
        absolute: false
    };
};

function Employee() {};

Employee.prototype = new Person();
Employee.prototype.celebrate = function () {
    this.age++;
}

var pete = new Employee();
pete.age = 5;
pete.celebrate();
var bob = new Employee();
bob.celebrate();
console.log("bob is " + bob.age + " pete is " + pete.age);

使用Employee.prototype = new Person();,所有Person的属性和(prototyped)方法都由Employee继承,这是继承的基础。

这可以按预期工作:bob is 1 pete is 6

现在我开始摆弄皮特的位置(庆祝之后)

pete.celebrate();
pete.location.absolute=true;

显示bob.location.absolute显示:true,这是直观的(我没有触及bob的位置,所以我希望它在Person中声明了初始值)并且破坏了我的解决方案。

在我最初的理解中,这应该是错误的。我确实意识到我可能应该从最初的Person克隆位置对象,但我不知道在哪里或如何做到这一点。 如果有更好的继承技术?

3 个答案:

答案 0 :(得分:3)

实例化新员工时,会复制Person的所有属性。由于这是浅拷贝,因此pete和bob共享相同的位置对象。对于您的问题,似乎没有一个非常好的解决方案。您既可以使用框架,也可以执行以下操作:

function Employee() { Person.apply(this); };

这将在此对象的上下文中调用Person构造函数。

MDC有更多信息:https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

答案 1 :(得分:3)

继承时不要运行Person构造函数,Employee不应该 甚至有一个.location,因为它不在Person.prototype

function createObject( fn ){
    function f(){}
    f.prototype = fn.prototype;
    return new f;
}

然后:

Employee.prototype = createObject( Person );

这将在没有副作用的情况下正确继承(运行构造函数)。

您只能在子构造函数中运行父构造函数:

function Employee() {
Person.apply( this, arguments );
}

答案 2 :(得分:0)

我遇到了类似的问题。我最终为内部对象使用了一个单独的构造函数。

function engine(cc, fuel) {
       this.cc = cc; 
       this.fuel = fuel
}

function car(type, model, cc, fuel) {
       this.type = type; 
       this.model = model;
       this.engine = new engine(cc, fuel);
}


var mycar = new car("sedan", "toyota corolla", 1500, "gas");
console.log(mycar.type);
//sedan
console.log(mycar.engine.cc);
//1500

如果我对'引擎'或'汽车'构造函数的原型有任何方法,它们仍然可用。但是,我并没有从OOP意义上的“引擎”类中推导出“汽车”类。我不需要。 “引擎”用作“汽车”的组成部分。

同时,对于继承,我更喜欢使用ECMAScript 5中包含的新方法,这意味着使用Object.create,Object.defineProperties等。即使在IE9中也支持它们。在此之前,我使用了Kosta建议的相同'apply()'方法。