在 Internet Explorer 中未定义 constructor.name

Posted

技术标签:

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

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

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

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

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

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

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

JSFIDDLE

【问题讨论】:

如果你正在缩小你的代码,那么constructor.name 可能最终会变成n 之类的东西,而不是你期望的对象名称。因此,即使没有 IE 问题,如果您希望它具有一定的价值,也要非常小心! 【参考方案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 之前),所以这并不奇怪。

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

javascript get Function Name? https://gist.github.com/dfkaye/6384439

更新

从 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 似乎工作正常,但是否推荐?

以上是关于在 Internet Explorer 中未定义 constructor.name的主要内容,如果未能解决你的问题,请参考以下文章

导航栏中的徽标在 Internet Explorer 中未正确居中

Bootstrap 模态样式的位置固定关闭按钮在 Internet Explorer 中未正确显示

Internet Explorer 8将我的网页显示为空白页,但在开发人员工具中未显示任何问题

我的自定义字体不想在 Internet Explorer 中使用

Internet Explorer 中不显示自定义字体

Internet Explorer 7 从 jQuery 类选择器返回“未定义”