使用javascript对象原型扩展类的问题

时间:2011-06-29 10:22:40

标签: javascript oop function-prototypes

我遇到了这个问题...... B是基类,A是派生类...虽然A是从B派生的,但是A的各个对象指向B的同一个对象。

我知道我已经将B的一个对象分配给A的原型以使A的孩子成为B.

但是A的不同对象,它们应该有不同的地址空间来容纳变量,对吧?你能纠正这个吗?

    function B(){

        this.obj = {};
    }

    function A(){

    }

    A.prototype = new B();

    var a = new A();
    var b = new A();
    var c = new A();

    console.log(a.obj == b.obj); //prints true
    console.log(a.obj === b.obj); //prints true

    a.obj.name = "stackoverflow";
    console.log(b.obj.name); //prints stackoverflow

我应该在此代码中做出哪些更改,以便为我提供以下结果。

a.obj === b.obj  //must be false

a instanceof A;  //must be true
a instanceof B;  //must be true

3 个答案:

答案 0 :(得分:4)

这就是为什么你不应该在原型上有可变值(特别是对象或数组) - 相同的值将在所有对象实例之间共享,并且可以在任何对象实例中进行更改。在这里,您可以使用在创建原型时不会调用B的构造函数的Object.create来避免此问题:

A.prototype = Object.create(B.prototype);

A的构造函数应该为每个新对象调用B的构造函数:

function A() {
  B.call(this);
}

对于不支持Object.create()的浏览器,您可以按照http://javascript.crockford.com/prototypal.html中的说明进行模拟。

答案 1 :(得分:2)

值是通过引用分配的,并且由于A的所有实例都使用与其原型相同的B实例,因此它们都引用相同的“B”。

所以这正是这里所期待的。解决这个问题的一种方法是在B'类'中添加(例如)'initialize'方法,然后可以从A构造函数中调用它。

你也可以使用'new B()'来定义原型,而是使用Object.create。 Object.create不会调用B的构造函数,但您可以从A中调用父构造函数。

function A() {
   B.call(this);
}

答案 2 :(得分:1)

这是Javascript原型的一部分,我建议你阅读this excellent thread