在这个小片段中可以看到这种行为(将其作为全局脚本执行):
var name = {};
name.FirstName = 'Tom';
alert(name.FirstName);
在Chrome中,警报会产生 undefined
,但在IE和Firefox中可以正常工作。当我执行以下操作时,我还会得到一个奇怪的值
alert(name);
在这个小片段中可以看到这种行为(将其作为全局脚本执行):
var name = {};
name.FirstName = 'Tom';
alert(name.FirstName);
在Chrome中,警报会产生 undefined
,但在IE和Firefox中可以正常工作。当我执行以下操作时,我还会得到一个奇怪的值
alert(name);
window.name 有特殊用途,应该是一个字符串。Chrome 显式地将其转为字符串,所以 var name = {};
实际上为全局变量 name
(即 window.name
)赋值为 "[object Object]"
。由于它是原始值,属性(name.FirstName
)不会“坚持住”。
要解决这个问题,不要使用 name
作为全局变量。
name
当作保留字来对待,因为有些主机也会给函数一个 name
属性(我以前就被这个问题咬过),闭包不会将其缩小,等等。 - Dagg Nabbit你的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
。除了更加简洁外,它还更加高效和明确。delete name;
。 - Oriol
language
属性已经被弃用,请仅使用type
属性。最好使用console.log
而不是alert
,并使用 Chrome Dev. Tools(或 FireBug)来读取它们。最后,在代码的第一行上需要有一个 doctype,格式为:<!doctype html>
。 - Wouter Jvar name = {}
语法更为常见。 - Hamish