我今天在IE中的调试工作结束时发现constructor.name
是undefined
。
我创建了以下简单代码来重现问题:
({}).constructor.name === undefined // => true
是否有任何解决方法可以使这项工作?
可能以某种方式压倒原型?
如果可能,我不想更改语法,因为更改将是主要的。
答案 0 :(得分:13)
/**
* 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');
car.constructor.name === 'Car'
car.constuctor === Car