行为可以在这个小片段中看到(将其作为全局脚本执行):
var name = {};
name.FirstName = 'Tom';
alert(name.FirstName);
警报undefined
在 Chrome 中产生,但在 IE 和 Firefox 中有效。当我这样做时,我也会得到一个奇怪的值
alert(name);
行为可以在这个小片段中看到(将其作为全局脚本执行):
var name = {};
name.FirstName = 'Tom';
alert(name.FirstName);
警报undefined
在 Chrome 中产生,但在 IE 和 Firefox 中有效。当我这样做时,我也会得到一个奇怪的值
alert(name);
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
. 除了更简洁之外,它还更高效、更明确。