JS - 无法获取函数实例的constructor.name

时间:2016-07-13 16:52:52

标签: javascript function constructor

我有一个函数(bar)的实例(foo),但bar.constructor.name返回"Object"而不是"foo"。谁能告诉我我做错了什么?

代码:

function foo(text){
    this.text = text;
}

foo.prototype = {
   getUppercase: function(){
      return this.text.toUpperCase();
    }
}

var bar = new foo("bar");
console.log(bar.constructor.name); //logs "Object" in Chrome

1 个答案:

答案 0 :(得分:2)

当您替换函数的prototype属性上的对象时,您必须负责修复其上的constructor属性:

foo.prototype = {
  constructor: foo,                  // <====
  getUppercase: function() {
    return this.text.toUpperCase();
  }
};

这不是自动的。该属性的唯一自动填充是在最初创建函数时分配给函数的prototype属性的默认对象。

function foo(text){
    this.text = text;
}

foo.prototype = {
  constructor: foo,
  getUppercase: function() {
    return this.text.toUpperCase();
  }
};

var bar = new foo("bar");
console.log(bar.constructor.name);

或者,替换prototype上的默认对象,只是增加它(通常是我的偏好):

foo.prototype.getUppercase = function() {
    return this.text.toUpperCase();
};

您可以通过Object.definePropertiesObject.assign(后者可能需要垫片)或您自己的实用程序功能执行多项操作。

最后,如果我没有提出一些事情,那将是我的疏忽:

  1. 压倒性地,构造函数名称以JavaScript中的大写字母开头。 只是一种惯例,但它是一个非常非常完善的惯例。

  2. 在ES2015 +中,您可以使用class获得更简洁的版本:

  3. Function#name是ES2015的新版本,我在2016年7月写这篇文章时支持有点粗略。(Chrome 51+确实拥有它。)

  4. FWIW:

    class Foo {
        constructor(text) {
            this.text = text;
        }
    
        getUppercase(){
            return this.text.toUpperCase();
        }
    }
    
    var bar = new Foo("bar");
    console.log(bar.constructor.name);

    当然,如果您需要支持较旧的引擎(如IE11),那么如果您这样做,则需要进行转换...(但话说再次,如果您使用的是Function#name,那也是来自ES2015。 )