Использование переменной "имя" не работает с объектом 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
, Помимо того, что это более кратко, это также более эффективно и более явно.