Использование переменной "name" не работает с объектом JS
Поведение можно увидеть в этом маленьком фрагменте (выполнить его как глобальный script):
var name = {};
name.FirstName = 'Tom';
alert(name.FirstName);
Предупреждение выводит undefined
в Chrome, но работает в IE и Firefox. Я также получаю странное значение, когда я делаю
alert(name);
Ответы
Ответ 1
window.name имеет особую цель и предполагается, что это строка. Chrome явно передает его в строку, поэтому var name = {};
на самом деле заканчивается тем, что для глобальной переменной name
(т.е. window.name
) значение "[object Object]"
. Поскольку это примитив, свойства (name.FirstName
) не будут "придерживаться".
Чтобы обойти эту проблему, не используйте name
как глобальную переменную.
Ответ 2
Ваша переменная 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);
})();
Ответ 3
window.name
используется для установки имени окна, и поскольку имя окна может быть только строкой, все, что вы установите на window.name
, преобразуется в строку. И строки, как примитивные значения, не могут иметь свойств. Решение состоит в том, чтобы использовать другое имя переменной или другую область.
В качестве альтернативы вы можете использовать window.name
, как вам нравится, если у вас есть этот код. Я не рекомендую это вообще, но, как доказательство концепции:
(function () {
var _name;
window.__defineGetter__('name', function () {
return _name;
});
window.__defineSetter__('name', function (v) {
_name = v;
});
})();
Кроме того, вместо new Object
следует использовать {}
. Помимо более кратких, он также более эффективен и более явчен.
Ответ 4
С помощью ES6+ вы можете написать свой код как let name
или const name
. Это не будет назначать или пытаться переопределить window.name
. Подробнее об этом здесь.
let name = {};
name.FirstName = 'Tom';
alert(name.FirstName);