Использование переменной "имя" не работает с объектом JS

Поведение можно увидеть в этом небольшом фрагменте (выполните его как глобальный скрипт):

var name = {};
name.FirstName = 'Tom';
alert(name.FirstName);

Предупреждение дает undefined в Chrome, но работает в IE и Firefox. Я также получаю странное значение, когда я делаю

alert(name);

3 ответа

Решение

window.name имеет специальное назначение и должно быть строкой. Похоже, что Chrome явно преобразует его в строку, поэтому var name = {}; на самом деле в конечном итоге дает глобальную переменную name (т.е. window.name) значение "[object Object]", Так как это примитивно, свойства (name.FirstName) не будет "прилипать".

Чтобы обойти эту проблему, не используйте name как глобальная переменная.

Ваш name переменная на самом деле window.name потому что переменные верхнего уровня объявлены с var прикреплены к глобальному объекту.

Спецификация HTML5 требует, чтобы window.name это DOMString, Это означает, что значение window.name может быть только последовательностью символов, но не объектом.

В Chrome попытка использовать window.name сохранение чего-либо, кроме примитивной строки, приведет значение к примитивной строке. Например:

window.name = {};
window.name === "[object Object]"; // true

Вы можете избежать этой проблемы, используя name переменная, которая не входит в область видимости верхнего уровня:

(function() {
    var name = {};
    // this `name` is not `window.name`
    // because we're not in the top-level scope

    console.log(name);
})();

С ES6+ вы можете написать свой код как let name или const name. Это не будет назначать его или пытаться переопределитьwindow.name. Подробнее об этом здесь.

let name = {};
name.FirstName = 'Tom';
alert(name.FirstName);

window.name используется для установки имени окна, и так как имя окна может быть только строкой, все, что вы установили на window.name преобразуется в строку. И строки, как примитивные значения, не могут иметь свойств. Решение состоит в том, чтобы использовать другое имя переменной или другую область видимости.

Кроме того, вы можете использовать window.name как вам нравится, если у вас есть этот код первым. Я не рекомендую это вообще, но, как подтверждение концепции:

(function () {
    var _name;
    window.__defineGetter__('name', function () {
        return _name;
    });
    window.__defineSetter__('name', function (v) {
        _name = v;
    });
})();

Кроме того, вы должны использовать {} на месте new Object, Помимо того, что это более кратко, это также более эффективно и более явно.

Другие вопросы по тегам