gpt4 book ai didi

分配时的 JavaScript 评估顺序

转载 作者:行者123 更新时间:2023-11-29 10:31:26 25 4
gpt4 key购买 nike

JavaScript 在什么时候确定赋值的左侧 - 是在评估右侧之前还是之后?

例如,这段代码的作用是什么?

var arr = [{thing:1},{thing:2},{thing:3},{last:true}];
arr[arr.length - 1].newField = arr.pop();

最佳答案

首先评估赋值运算符的左侧。

关于 ES2015 的规范可以在 "Runtime Semantics: Evaluation" portion of the "Assignment Operators" section 中找到可以非常粗略地概括为:

  1. 评估 LHS 以确定引用
  2. 评估 RHS 以确定值
  3. 为引用赋值

关于数组 .pop() 示例,它可能看起来会将最初的最后一项分配给结果最后一项中的字段——但这只会发生在 RHS首先评估,而不是 LHS。

实际发生的是左侧首先产生对原始最后一个对象 {last:true} 的引用。在此之后,array.pop() 从数组末尾移除后返回相同的对象。然后分配发生,所以对象最终看起来像 obj =
{last:true, newField:obj}
。由于原始示例中没有保留对 obj 的引用,

将赋值扩展到代码中,并添加一些额外的变量以便我们检查行为,可能看起来像这样:

function pseudoAssignment() {
// left-hand side evaluated first
var lhsObj = arr[arr.length - 1];
var lhsKey = 'newField';

// then the right-hand side
var rhsVal = arr.pop();

// then the value from RHS is assigned to what the LHS references
lhsObj[lhsKey] = rhsVal;

// `(a = b)` has a value just like `(a + b)` would
return rhsVal;
}

var arr = [{thing:1},{thing:2},{thing:3},{last:true}];
_lastObj = arr[arr.length - 1];

// `arr[arr.length - 1].newField = arr.pop();`
_result = pseudoAssignment();

console.assert(_lastObj.newField === _lastObj,
"The last object now contains a field recursively referencing itself.")
console.assert(_result === _lastObj,
"The assignment's result was the object that got popped.")
console.assert(arr.indexOf(_lastObj) === -1,
"The popped object is no longer in the array.")

关于分配时的 JavaScript 评估顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45247309/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com