如何获取子构造函数的名称?

时间:2013-05-07 14:40:10

标签: javascript

我有一个带有原型方法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的构造函数的名称?

6 个答案:

答案 0 :(得分:4)

Working fiddle

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

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'.

答案 1 :(得分:3)

您正在将Parent的原型对象分配给Child.prototype - 这意味着每个子实例都从与所有父实例相同的东西继承,当然它们继承了相同的constructor这样的财产。

相反,为Child.prototype创建一个新对象,继承自Parent.prototype,然后您可以覆盖constructor属性:

Child.prototype = Object.create(Parent.prototype, {
    constructor: {value: Child, configurable: true}
});

答案 2 :(得分: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();

答案 3 :(得分: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

答案 4 :(得分: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/

答案 5 :(得分:0)

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