为什么这个非常棘手的计算属性名称函数的工作方式呢? [英] Why does this really tricky computed property name function works the way it does?

查看:89
本文介绍了为什么这个非常棘手的计算属性名称函数的工作方式呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

@ 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆