0

我有一个带有原型方法的类,printConstructorName它打印构造函数的名称:

function Parent(){
}

Parent.prototype.printConstructorName = function(){
   console.log(this.constructor.name);
};

var parent = new Parent();
parent.printConstructorName(); // It gets 'Parent'.

一个类通过原型Child继承:Parent

function Child()
{
}

Child.prototype = Parent.prototype;

var child = new Child();
child.printConstructorName(); // It gets 'Parent', but 'Child' is necessary.

如何通过Parent的原型方法获取Child的构造函数名称?

4

6 回答 6

4

工作小提琴

继承模式是问题所在。这是快速修复:

function inherits(childCtor, parentCtor) {
  function tempCtor() {};
  tempCtor.prototype = parentCtor.prototype;
  childCtor.prototype = new tempCtor();
  childCtor.prototype.constructor = childCtor;
};

function Parent(){}

Parent.prototype.printConstructorName = function(){
   return this.constructor.name;
};

var parent = new Parent();
console.log(parent.printConstructorName()); // It gets 'Parent'.

function Child() {
    Parent.call(this);
};
inherits(Child, Parent);

var child = new Child();
console.log(child.printConstructorName()); // It gets 'Child'.
于 2013-05-07T14:50:23.863 回答
3

您将Parents 原型对象分配给Child.prototype- 这意味着每个子实例都继承自与所有父实例相同的事物,当然它们以constructor这种方式继承相同的属性。

Child.prototype取而代之的是,为继承创建一个新对象Parent.prototype,然后您可以覆盖该constructor属性:

Child.prototype = Object.create(Parent.prototype, {
    constructor: {value: Child, configurable: true}
});
于 2013-05-07T14:49:36.733 回答
3

你的继承机制显然是错误的。按照你的做法,如果你给 Child.prototype 添加一个属性,所有的 Parent 对象也会得到它......

您可能需要这样的inherit函数:

inherit = (function() {
    function F() {};
    return function(parent, child) {
        F.prototype = parent.prototype;
        child.prototype = new F();
        child.prototype.constructor = child;
    };
}());

然后你可以使用这种方式:

function Parent() {
}

Parent.prototype.printConstructorName = function(){
   console.log(this.constructor.name);
};

var parent = new Parent();
parent.printConstructorName();  // Parent

function Child() {
}

inherit(Parent, Child);

var child = new Child(); // Child
child.printConstructorName();
于 2013-05-07T14:51:02.943 回答
1

在扩展现有构造函数时,应将子原型设置为父类的实例,以便对子原型的更改不会影响父原型。

然后你可以简单地覆盖constructor它指向正确的函数。

function Parent() {
    ....code...
}

Parent.prototype.printConstructorName = function () {
    console.log(this.constructor.name);
};

function Child() {
    ...code...
}

Child.prototype = new Parent();
Child.prototype.constructor = Child;

p = new Parent();
p.printConstructorName(); //Parent

c = new Child();
c.printConstructorName(); //Child
于 2013-05-07T14:50:55.563 回答
1

编写一个扩展函数,例如:

__extend = function(child, sup) {
    for (prop in sup.prototype) {
        child.prototype[prop] = sup.prototype[prop];
    };
};

然后你调用它而不是做prototype = new parent伎俩 - 比如:

var Parent = function() {}
Parent.prototype.name = function() { return "name" };

var Child = function() {}
__extend(Child, Parent);

看看这个小提琴:http: //jsfiddle.net/Cmg4A/

于 2013-05-07T14:53:47.003 回答
0

也许您应该覆盖 Child :D 中的 printConstructorName。

于 2013-05-07T14:44:18.170 回答