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