Constructor.name undefined в Internet Explorer
Моя работа по отладке в IE закончилась сегодня, обнаружив, что constructor.name
- undefined
.
Я создал следующий простой код, который воспроизводит проблему:
({}).constructor.name === undefined // => true
Есть ли способ обхода этой работы?
Может быть, как-то переопределить прототип?
Если возможно, я не хочу менять синтаксис, потому что изменение будет значительным.
JSFIDDLE
Ответы
Ответ 1
Проблема заключается в том, что свойство name
объектов функции не поддерживается в Internet Explorer. Свойство нестандартно (вплоть до ECMAScript 6, по крайней мере), так что это не удивительно.
Существует не вполне надежное обходное решение, поэтому я предлагаю попытаться обойтись без него, если это возможно. Однако вы можете извлечь имя из строкового представления функции. Вот несколько ссылок, которые касаются этого, что я получил от быстрого поиска:
Обновление
Из комментариев выясняется, что целью автора вопроса является проверка того, является ли переменная ссылкой на простой объект, созданный конструктором Object
. Надежным способом сделать это для переменной a
является
Object.prototype.toString.call(a) == "[object Object]"
Для получения дополнительной информации я рекомендую следующую страницу, написанную Ангусом Кроллом:
http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/
Ответ 2
От 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) {}
});
}
Ответ 3
Возможно, этот пример проясняет некоторую путаницу.
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
Ответ 4
Это импровизация от Оливера.
Вместо использования регулярного выражения этот метод будет один раз анализировать строку и сохранять ее в области видимости, чтобы избежать проблем с производительностью, если он вызывался более одного раза.
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;
}
});
}
Ответ 5
легко исправить без "изменения синтаксиса" или полифилла;)
ES6
car.constructor.name === 'Car'
ES5 (IE)
car.constuctor === Car