我喜欢认为我理解JavaScript,但今天我发现了一些意想不到的东西,我希望有人可以向我解释它为什么会发生。
拿这个代码
var animalData = {
cow:"cow",
sheep:"sheep",
getCow:function()
{
return this.cow;
},
animalList:[
{
animalId:this.cow,
label:"This is a cow"
},
{
animalId:this.sheep,
label:"This is a sheep"
}
]
};
console.log(animalData.getCow());
console.log(JSON.stringify(animalData.animalList,null," "))
输出不是我所期望的。正如您所料,调用animalData.getCow()
会产生"cow"
。但是第二个让我感到困惑的console.log
会让你回归。
[
{
"label": "This is a cow"
},
{
"label": "This is a sheep"
}
]
换句话说,该对象完全从定义的对象中删除animalId
属性。我在期待这个
[
{
"animalId":"cow",
"label": "This is a cow"
},
{
"animalId":"sheep",
"label": "This is a sheep"
}
]
我可以理解这个
[
{
"animalId":undefined,
"label": "This is a cow"
},
{
"animalId":undefined,
"label": "This is a sheep"
}
]
但为什么animalId
属性会被完全删除?
任何人都可以解释表面下发生的事情导致这种行为吗?我猜测this
关键字不起作用,因为调用它时属性是未定义的,但为什么它会完全删除属性?
注意:我不是在寻找一种解决方法,这很容易做到 - 只关心它为什么会发生。
答案 0 :(得分:6)
在对象初始化时,this
引用外部上下文,它不具有cow
和sheep
属性。如您所愿,这将导致animalId
成为undefined
。
undefined
属性的 JSON.stringify
does certain things,即:
如果在转换过程中遇到
undefined
,函数或符号,则省略(当在对象中找到它时)或删除null
(当它在一个数组中找到)。
这就是你没有看到它们的原因。
答案 1 :(得分:4)
首先,你的上一个例子是正确的,这就是你想要字符串化的内容:
X.t
并且,因为这些值未定义[
{
"animalId":undefined,
"label": "This is a cow"
},
{
"animalId":undefined,
"label": "This is a sheep"
}
]
只是省略它们。
为什么上面的值未定义是因为JSON.stringify
中的this
关键字引用了当前范围,实际上是this.cow
对象,因为它不在任何其他函数内。
为什么省略具有window
值的键是有意义的?因为它们是否存在,如果您尝试访问undefined
,您将获得正确的值:object.key