为什么这个非常棘手的计算属性名称函数的工作方式呢? [英] Why does this really tricky computed property name function works the way it does?
问题描述
@ raina77ow最近帮我找出了计算属性名称。作为他们对我的问题的回答的一部分,他们分享了一些非常棘手的代码,展示了JavaScript的有趣方面:
@raina77ow recently helped me figure out computed property names. As part of their answer to my question, they shared a really tricky bit of code showcasing interesting aspects of JavaScript:
const increment = (() => { let x = 0; return () => ++x })();
const movingTarget = { toString: increment };
const weirdObjectLiteral = { [movingTarget]: 42 };
console.log( weirdObjectLiteral[movingTarget] ); // undefined
当我在节点CLI中运行该样本时,最后一行不断输出 undefined
,而 x
中的值增量
不断递增。
When I run that sample in the node CLI, that last line continually outputs undefined
, while the value x
in increment
continually increments.
如果我们用替换
,此行为不再发生,而是输出 const movingTarget = {toString:increment};
const movingTarget = {[toString]:increment}; 42
和 x
in increment
保持不变。
If we replace const movingTarget = { toString: increment };
with const movingTarget = { [toString]: increment };
, this behaviour ceases to take place, and instead we get an output of 42
and the x
in increment
remains the same.
有人可以帮我理解为什么会这样吗?是什么让JavaScript以这种方式工作?
Can somebody help me understand why this is the case? What is it about JavaScript that makes things work this way?
相关问题:中的函数
存在,直到我们从内存中明确删除 x
> increment increment
?
Related Question: Does the x
in the function within increment
exist until we explicitly remove increment
from memory?
推荐答案
让我们评估以下对象文字:
Lets evaluate the following object literal:
{[toString]: increment }
toString
是一个指向的标识符window.toString
(一个函数)如答案所述, toString
将被调用,因为对象键总是字符串:
toString
is an identifier pointing to window.toString
(a function) As outlined by the answer, toString
will be called on that as object keys are always strings:
{[toString.toString()]: increment }
现在产生的结果如下:
{["function() { [native code] }"]: increment }
现在如果我们在这个对象上调用 toString()
,标准的 Object.prototype.toString
将会得到在 {[movingTarget]:42}
部分调用,结果是 [Object object]
(一如既往):
Now if we call toString()
on this object, the standard Object.prototype.toString
will get called in the {[movingTarget]: 42}
part and the result is [Object object]
(as always):
let x = 0;
let movingTarget = { ["function() { [native code] }"]: () => ++x };
console.log(
movingTarget.toString(), // [Object object]
{[movingTarget]: 42} // {["[Object object]"]: 42}
);
这就是移动目标不再移动的原因。在原始代码中,设置了对象的 toString
,只要 movingTarget
变为字符串,就会调用它:
thats why the moving target isnt moving anymore. In the original code, toString
of the object was set, and that gets called whenever movingTarget
gets turned into a string:
let x = 0;
let movingTarget = { toString: () => ++x };
console.log(
movingTarget.toString(), // 1
"" + movingTarget, // 2
{[movingTarget]: 42} // { 3: 42 }
);
这篇关于为什么这个非常棘手的计算属性名称函数的工作方式呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!