我正在阅读一本书 JavaScript:The Good Parts ,以增加我的JavaScript知识。在作者所说的第3章对象中:
对象是属性的容器,其中属性具有名称和值。属性名称可以是任何字符串,包括空字符串。属性值可以是任何JavaScript值,但未定义。
作者的意思是什么?据我所知,我们可以使用原型单词在对象文字中或在对象文字外部将值设置为undefined。例如,Object.prototype.customName = undefined;
效果很好。我在这里错过了什么?
答案 0 :(得分:2)
您可以将值undefined
分配给属性,甚至可以定义具有undefined
属性的文字;但是,生成的对象很容易混淆与没有该属性的类似对象。
例如,在Node:
中> x = {a: 1, b: undefined}
{ a: 1, b: undefined }
> y = {a: 1}
{ a: 1 }
> x.a
1
> y.a
1
> x.b
undefined
> y.b
undefined
> Object.keys(x)
[ 'a', 'b' ]
> Object.keys(y)
[ 'a' ]
> JSON.stringify(x)
'{"a":1}'
> JSON.stringify(y)
'{"a":1}'
作者似乎在说,如果你想编写好的,负责任的代码,你不应该使用undefined
作为属性值,因为你可能会要求混淆。
但从语义上来说,undefined
确实存在,所以如果你从字面上解释作者所说的内容,那么它在技术上是不正确的。但是如果你遵循最佳实践,我就能看到他想要碰到的东西。它非常像克罗克福德式。
顺便说一句,删除属性的正确方法是使用delete
,但这可能是针对不同的问题。
<强>附录强>
在回复@prsvr的评论中的一个问题时,我查找了旧的ECMAScript 3规范并找到了以下内容:
ECMAScript是基于对象的:基础语言和主机设施由对象提供,ECMAScript程序是通信对象的集群。 ECMAScript对象是一个无序的属性集合,每个属性都有零个或多个属性,用于确定每个属性的使用方式 - 例如,当属性的ReadOnly属性设置为true时,执行ECMAScript代码的任何尝试都会更改值该物业无效。属性是容纳其他对象,原始值或方法的容器。 ECMAScript语言原语值是以下内置类型之一的成员:Undefined,Null,Boolean,Number和String;对象是以下内置类型之一的成员:Undefined,Null,Boolean,Number和String;对象是剩余的内置类型Object的成员;方法是通过属性与对象相关联的函数。
在规范中没有提及undefined
被禁止作为属性值。 (https://www-archive.mozilla.org/js/language/E262-3.pdf)。
在JavaScript的演变过程中有一些未定义的变化;例如,您曾经能够将标识符 undefined
的值重新分配给undefined以外的某个值,因此成语typeof(x) === "undefined"
(等等)。
答案 1 :(得分:0)
我认为作者试图说明在没有定义其价值的情况下无法定义对象的关键字。也就是说,密钥应始终具有值。
例如,如果定义了键test
而未定义其值,则会引发错误。
var abc = {
test:
}
答案 2 :(得分:0)
我认为是因为js对象认为undefined
和inactive key
都是默认值
unknown key
因此,如果将对象的键值分配给var person = {
name: 'name',
'': 'this is empty key',
null: 'this is null key',
another_null: null,
undefined: 'this is undefined key',
inactive_key: undefined
}
console.log(person['key_from_nowhere']) // unknown key => undefined
console.log(person.hasOwnProperty('key_from_nowhere')) // false
console.log(person['inactive_key']) // undefined
console.log(person.hasOwnProperty('inactive_key')) // true
,则此键属于undefined
情况(JSON.stringify将忽略)
inactive key
顺便说一句,我发现分配person.name = undefined;
console.log(JSON.stringify(person)); // name will disappear
可能会引起混乱和容易出错,因为逻辑代码必须使用undefined
来检查密钥是否存在,所以您认为这里的最佳实践是{{ 1}}?