JavaScript - 计算属性 - 深度混淆
JavaScript - Computed properties - deep confusion
似乎我对 JavaScript 中的计算属性感到很困惑。
当我定义一个对象并将 [d]
作为键(作为 属性 key/name)时,这个 [d]
实际上做了什么?似乎对于某些值 d
它计算 s = d.toString()
并使用该值 s
作为 属性 键。
但是对于其他值 d
(例如,当 d
是一个符号时)它实际上使用符号的值作为键。
所以 [d]
的这种双重行为(作为语法结构)似乎令人困惑。有人可以深入解释这是如何工作的吗?
还有其他特殊情况吗?还是当 d
是 Symbol 时我们有这种特殊行为?
回到基础:什么事物可以是对象的keys/names属性?它只是字符串还是只是字符串和符号,还是还有一些额外的......?
示例:
var symbol = Symbol("test");
function Animal(name){
this.name = name;
}
Animal.prototype = {};
Animal.prototype.constructor = Animal;
function Dog(breed){
this.breed = breed;
this.name = "Dog";
this.s = symbol;
}
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
console.log("001");
var d = new Dog("Sharo");
for (let x in d){
console.log(x, ":", d[x]);
}
console.log("002");
d = new Object();
for (let x in d){
console.log(x, ":", d[x]);
}
console.log("003");
d = new Number(5);
for (let x in d){
console.log(x, ":", d[x]);
}
var d1 = {};
var d2 = {};
var d = new Dog("Sharo");
var m = {[d1] : 5, [d2] : 10, [d] : 20, z : 100, symbol: 2000, [symbol] : 5000};
console.log("============================");
console.log(m);
for (let x in m){
console.log(x, ":", m[x]);
}
console.log("============================");
由于似乎没有人有兴趣回答这个问题,我将根据上面得到的评论自己回答,因此我不再感到困惑。
请注意,这里的答案是基于 ES6 的。我的意思是...谁知道 JavaScript 的未来还会怎样 :)
When I define an object and I put [d]
as a key (as a property key/name) what does this [d]
actually do? Seems that for some objects d
it calculates s = d.toString()
and uses that value s
as the property key. But for other objects d
(e.g. when d
is a Symbol) it uses really the Symbol's value as the key.
是的,没错。当 d 是 Symbol 时,直接使用它的值。当 d 不是 Symbol 时,它的值被强制转换为一个字符串,并且该字符串用作 属性 name/key。强制转换更像是 String(d)
而不是 d.toString()
。
So this dual behavior of [d]
(as a syntax construct) seems confusing. Could someone explain in depth how this works?
上面已经解释过了。
Are there other special cases btw? Or is it just when d
is a Symbol when we have that special behavior?
没有其他"special cases"。从 ES6 开始,只有字符串和符号可以是 属性 键。
Back to the basics: what things can be keys/names of properties of an object? Is it just strings or just strings and symbols or is there also something additional... ?
如前所述,从 ES6 开始,只有字符串和符号可以是 属性 键。
参考文献:
(1)
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors
"Property names are string or Symbol. Any other value, including a number, is coerced to a string."
(2)
https://www.ecma-international.org/ecma-262/6.0/#sec-topropertykey
在对另一个答案的评论中,您说您认为 属性 键总是字符串。在 ES2015 之前,它们 是 。 :-)
So this dual behavior of [d]
(as a syntax construct) seems confusing. Could someone explain in depth how this works?
从 ES2015 开始,Symbols 被添加到语言中,对象 属性 键可以是字符串或 Symbols。所以当你这样做时:
const obj = {
[d]: "foo"
};
...计算出的 属性 键 ([d]: "foo"
) 的一部分是这样工作的:
- 令
value
为计算表达式 "foo"
的结果
- 令
keyValue
为计算表达式 d
的结果
- 如果
keyValue
是一个Symbol,让key
= keyValue
;否则,设 key
= String(keyValue)
- 将
obj
上的 属性 key
设置为值 value
为了清楚起见,我在其中省略了一些细节。您可以在规范中的 ToPropertyKey 抽象操作中看到,只要将值用作 属性 键(在上面的对象文字中,或者访问对象 属性 通过括号符号等)。
Are there other special cases btw? Or is it just when d is a Symbol when we have that special behavior?
Back to the basics: what things can be keys/names of properties of an object? Is it just strings or just strings and symbols or is there also something additional... ?
只是符号和字符串。 :-) 与其说 Symbol 是一个 特例 ,还不如说 属性 键以前总是字符串,现在它们可以是字符串 或符号。
(有趣的事实:在规范中,they define "property key" as the string or Symbol that identifies a property, and "property name" as a property key that's a string. But don't rely on it, the spec itself is a bit inconsistent, and the Object.keys
method — which returns an array of property names, not property keys — existed before that terminology was added in ES2015. And then they added a keys
method to arrays that returns an iterator of numbers [the indexes 在数组中。有趣有趣...:-))
在 ES2015 中指定所有返回或循环遍历 属性 名称的 ES5 和更早版本的操作,以忽略符号键控属性。所以for-in
、Object.keys
、Object.getOwnPropertyNames
都只看字符串键控的属性。 ES2015 添加了 Reflect.ownKeys
(包括字符串和符号)和 Object.getOwnPropertySymbols
(仅包括自己的符号键属性)。
旁注:
Seems that for some objects d it calculates s = d.toString() and uses that value s as the property key...
不只是对象,它更像是 String(d)
(尽管如果 d
是一个对象,则结果相同)。任何不是字符串或符号的内容都将转换为字符串。
...But for other objects d (e.g. when d is a Symbol) it uses really the Symbol's value as the key.
Symbols 不是对象,Symbol 是原始类型。但是,是的,如果 属性 键是一个 Symbol,则直接使用它,而不是转换为字符串。
似乎我对 JavaScript 中的计算属性感到很困惑。
当我定义一个对象并将 [d]
作为键(作为 属性 key/name)时,这个 [d]
实际上做了什么?似乎对于某些值 d
它计算 s = d.toString()
并使用该值 s
作为 属性 键。
但是对于其他值 d
(例如,当 d
是一个符号时)它实际上使用符号的值作为键。
所以 [d]
的这种双重行为(作为语法结构)似乎令人困惑。有人可以深入解释这是如何工作的吗?
还有其他特殊情况吗?还是当 d
是 Symbol 时我们有这种特殊行为?
回到基础:什么事物可以是对象的keys/names属性?它只是字符串还是只是字符串和符号,还是还有一些额外的......?
示例:
var symbol = Symbol("test");
function Animal(name){
this.name = name;
}
Animal.prototype = {};
Animal.prototype.constructor = Animal;
function Dog(breed){
this.breed = breed;
this.name = "Dog";
this.s = symbol;
}
Dog.prototype = new Animal();
Dog.prototype.constructor = Dog;
console.log("001");
var d = new Dog("Sharo");
for (let x in d){
console.log(x, ":", d[x]);
}
console.log("002");
d = new Object();
for (let x in d){
console.log(x, ":", d[x]);
}
console.log("003");
d = new Number(5);
for (let x in d){
console.log(x, ":", d[x]);
}
var d1 = {};
var d2 = {};
var d = new Dog("Sharo");
var m = {[d1] : 5, [d2] : 10, [d] : 20, z : 100, symbol: 2000, [symbol] : 5000};
console.log("============================");
console.log(m);
for (let x in m){
console.log(x, ":", m[x]);
}
console.log("============================");
由于似乎没有人有兴趣回答这个问题,我将根据上面得到的评论自己回答,因此我不再感到困惑。
请注意,这里的答案是基于 ES6 的。我的意思是...谁知道 JavaScript 的未来还会怎样 :)
When I define an object and I put
[d]
as a key (as a property key/name) what does this[d]
actually do? Seems that for some objectsd
it calculatess = d.toString()
and uses that values
as the property key. But for other objectsd
(e.g. whend
is a Symbol) it uses really the Symbol's value as the key.
是的,没错。当 d 是 Symbol 时,直接使用它的值。当 d 不是 Symbol 时,它的值被强制转换为一个字符串,并且该字符串用作 属性 name/key。强制转换更像是 String(d)
而不是 d.toString()
。
So this dual behavior of
[d]
(as a syntax construct) seems confusing. Could someone explain in depth how this works?
上面已经解释过了。
Are there other special cases btw? Or is it just when
d
is a Symbol when we have that special behavior?
没有其他"special cases"。从 ES6 开始,只有字符串和符号可以是 属性 键。
Back to the basics: what things can be keys/names of properties of an object? Is it just strings or just strings and symbols or is there also something additional... ?
如前所述,从 ES6 开始,只有字符串和符号可以是 属性 键。
参考文献:
(1) https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors
"Property names are string or Symbol. Any other value, including a number, is coerced to a string."
(2) https://www.ecma-international.org/ecma-262/6.0/#sec-topropertykey
在对另一个答案的评论中,您说您认为 属性 键总是字符串。在 ES2015 之前,它们 是 。 :-)
So this dual behavior of
[d]
(as a syntax construct) seems confusing. Could someone explain in depth how this works?
从 ES2015 开始,Symbols 被添加到语言中,对象 属性 键可以是字符串或 Symbols。所以当你这样做时:
const obj = {
[d]: "foo"
};
...计算出的 属性 键 ([d]: "foo"
) 的一部分是这样工作的:
- 令
value
为计算表达式"foo"
的结果
- 令
keyValue
为计算表达式d
的结果
- 如果
keyValue
是一个Symbol,让key
=keyValue
;否则,设key
=String(keyValue)
- 将
obj
上的 属性key
设置为值value
为了清楚起见,我在其中省略了一些细节。您可以在规范中的 ToPropertyKey 抽象操作中看到,只要将值用作 属性 键(在上面的对象文字中,或者访问对象 属性 通过括号符号等)。
Are there other special cases btw? Or is it just when d is a Symbol when we have that special behavior?
Back to the basics: what things can be keys/names of properties of an object? Is it just strings or just strings and symbols or is there also something additional... ?
只是符号和字符串。 :-) 与其说 Symbol 是一个 特例 ,还不如说 属性 键以前总是字符串,现在它们可以是字符串 或符号。
(有趣的事实:在规范中,they define "property key" as the string or Symbol that identifies a property, and "property name" as a property key that's a string. But don't rely on it, the spec itself is a bit inconsistent, and the Object.keys
method — which returns an array of property names, not property keys — existed before that terminology was added in ES2015. And then they added a keys
method to arrays that returns an iterator of numbers [the indexes 在数组中。有趣有趣...:-))
在 ES2015 中指定所有返回或循环遍历 属性 名称的 ES5 和更早版本的操作,以忽略符号键控属性。所以for-in
、Object.keys
、Object.getOwnPropertyNames
都只看字符串键控的属性。 ES2015 添加了 Reflect.ownKeys
(包括字符串和符号)和 Object.getOwnPropertySymbols
(仅包括自己的符号键属性)。
旁注:
Seems that for some objects d it calculates s = d.toString() and uses that value s as the property key...
不只是对象,它更像是 String(d)
(尽管如果 d
是一个对象,则结果相同)。任何不是字符串或符号的内容都将转换为字符串。
...But for other objects d (e.g. when d is a Symbol) it uses really the Symbol's value as the key.
Symbols 不是对象,Symbol 是原始类型。但是,是的,如果 属性 键是一个 Symbol,则直接使用它,而不是转换为字符串。