【问题标题】:constructor.name is undefined in Internet Explorer在 Internet Explorer 中未定义 constructor.name
【发布时间】:2014-09-28 05:28:15
【问题描述】:

我在 IE 中的调试工作今天结束,发现 constructor.nameundefined

我创建了以下重现问题的简单代码:

({}).constructor.name === undefined // => true

是否有任何解决方法可以使这项工作?

也许会以某种方式覆盖原型?

如果可能,我不想更改语法,因为更改将是重大的。

JSFIDDLE

【问题讨论】:

  • 如果你正在缩小你的代码,那么constructor.name 可能最终会变成n 之类的东西,而不是你期望的对象名称。因此,即使没有 IE 问题,如果您希望它具有一定的价值,也要非常小心!

标签: javascript internet-explorer object constructor


【解决方案1】:

wrote this 满足我的需要(承认它可能不是完全证明):

if (!Object.constructor.prototype.hasOwnProperty('name')) {
    Object.defineProperty(Object.constructor.prototype, 'name', {
        get: function () {
            return this.toString().trim().replace(/^\S+\s+(\w+)[\S\s]+$/, '$1');
        }
    })
}

在该方法中执行的正则表达式假设第二个非空白字符组 IS 是构造函数的名称。对于我正在使用的代码来说,这是一个可行的解决方案,虽然这可能无法完全满足所有其他人的需求。

【讨论】:

    【解决方案2】:

    也许这个例子可以消除一些困惑。

    var number = 10;        //A global variable. Part of the global window object.
    //window.number = 10;   //Does exactly the same as the line above.
    
    
    var customer = {
        number: 20,
        speak: function () {
            if (this === window) {
                alert('I am being called by go() ' + this.number);      //this.number points to the global variable number
            } else {
                alert('I am being called by customer.speak ' + this.number);  //this.number points to the customer member number
            }
        }
    }
    
    var go = customer.speak;  //Go now points directly to the function called "speak" as if it is not a part of the customer object. The this parameter of speak will be the global window object;
    
    go();
    customer.speak();         //Now the speak function is called a part of the customer object. The this parameter of speak will be the customer object
    

    【讨论】:

    • 我不明白:Window === Window.constructor // false.
    • 通过使用 if (this === window) 我不需要 constructor.name 属性。
    【解决方案3】:

    这是奥利弗回答的即兴创作。

    此方法不使用正则表达式,而是将字符串解析一次并将其保存到范围内,以避免多次调用时出现性能问题。

    if(Function.prototype.name === undefined){
        Object.defineProperty(Function.prototype, 'name', {
            get:function(){
                if(!this.__name)
                    this.__name = this.toString().split('(', 1)[0].split(' ')[1];
                return this.__name;
            }
        });
    }
    

    【讨论】:

      【解决方案4】:

      来自matt.scharley.me

      /**
       * Hack in support for Function.name for browsers that don't support it.
       * IE, I'm looking at you.
      **/
      if (Function.prototype.name === undefined && Object.defineProperty !== undefined) {
          Object.defineProperty(Function.prototype, 'name', {
              get: function() {
                  var funcNameRegex = /function\s([^(]{1,})\(/;
                  var results = (funcNameRegex).exec((this).toString());
                  return (results && results.length > 1) ? results[1].trim() : "";
              },
              set: function(value) {}
          });
      }
      

      【讨论】:

      • 请注意,这不适用于var TestFunction1 = function() {}; console.log('TestFunction1.name', TestFunction1.name);
      【解决方案5】:

      问题只是 Internet Explorer 不支持函数对象的 name 属性。该属性是非标准的(至少在 ECMAScript 6 之前),所以这并不奇怪。

      没有完全可靠的解决方法,所以我建议尽可能不使用它。但是,您可以从函数的字符串表示中提取名称。这是我从快速搜索中获得的几个处理此问题的链接:

      更新

      从 cmets 来看,问题作者的目标是测试一个变量是否是对 Object 构造函数创建的普通对象的引用。对变量 a 执行此操作的可靠方法是

      Object.prototype.toString.call(a) == "[object Object]"
      

      有关更多信息,我推荐 Angus Croll 编写的以下页面:

      http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

      【讨论】:

      • Object.prototype.constructor.name = "Object" 这样的事情怎么样?能解决问题吗?
      • @IonicăBizău:如果你觉得它有帮助,你当然可以这样做,尽管我建议选择不同的属性名称,以防name 属性在支持name 的浏览器中不可写。
      • @TimDown:function.name 属性是不可写的(如 Mozilla 文档中所述)。但是,如果它是不可写的,为什么你认为应该避免它呢?
      • @gwag:我更愿意单独保留原生属性和方法,而不是尝试填充它们,但在这种情况下,我认为这没有多大意义。
      • @TimDown a.constructor === Object 似乎工作正常,但是否推荐?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多