在Internet Explorer中未定义constructor.name

时间:2014-08-05 14:00:42

标签: javascript internet-explorer object constructor

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

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

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

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

可能以某种方式压倒原型?

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

JSFIDDLE

6 个答案:

答案 0 :(得分:13)

来自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) {}
    });
}

答案 1 :(得分:11)

问题很简单,Internet Explorer不支持函数对象的name属性。该属性是非标准的(至少在ECMAScript 6之前),所以它并不令人惊讶。

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

<强>更新

从评论中可以看出,问题作者的目标是测试变量是否是对Object构造函数创建的普通对象的引用。为变量a执行此操作的可靠方法是

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

有关详细信息,我建议使用Angus Croll撰写的以下页面:

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

答案 2 :(得分:1)

也许这个例子清除了一些混乱。

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

答案 3 :(得分:0)

这是奥利弗回答的即兴表演。

此方法不是使用正则表达式,而是将字符串解析一次并将其保存到作用域中,以避免在多次调用时导致性能问题。

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 :(得分:0)

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 是构造函数的名称。对于我正在使用的代码,这是一个可行的解决方案,尽管这可能无法完全满足其他所有需求。

答案 5 :(得分:-1)

易于修复,无需“更改语法”或polyfill;)

var car = new Car('ferrari');

ES6

car.constructor.name === 'Car'

ES5(IE)

car.constuctor === Car