javascript - 'array[array.length - 1] = array.pop()' 会产生未定义的行为吗?

标签 javascript arrays node.js

我一直在尝试实现一种方法,该方法将数组和索引作为输入,将给定数组的最后一个元素复制到给定索引处的条目中,然后 chop 最后一个元素(即设置数组短一个)。

这是我作为此任务的建议给出的功能:

function swapWithLastAndRemove(array, index) {
    array[index] = array.pop();
}

然后我测试了这个函数以确保它适用于任何给定的索引:

for (let index = 0; index < 5; index++) {
    var array = [0, 1, 2, 3, 4];
    swapWithLastAndRemove(array, index);
    console.log(array);
}

而且我发现它对除最后一个索引以外的所有索引都能正常工作:

[ 4, 1, 2, 3 ]
[ 0, 4, 2, 3 ]
[ 0, 1, 4, 3 ]
[ 0, 1, 2, 4 ]
[ 0, 1, 2, 3, 4 ]

换句话说,对于最后一个元素,它将它从数组中弹出,然后将其重写到数组中。

令我印象深刻的是这一行:

array[index] = array.pop();

在最后一个元素上执行时相当于此行:

array[array.length - 1] = array.pop();

不可能导致 array 的内容等于 [ 0, 1, 2, 3, 4 ]

在我看来,这里有两个选项:

  1. 语句array.pop() 在表达式array.length - 1 被求值之前执行
  2. 语句array.pop() 在表达式array.length - 1 求值后执行

在第一种情况下,数组的内容会发生如下变化:

  • [ 0, 1, 2, 3, 4 ]//初始状态
  • [ 0, 1, 2, 3 ]//弹出 4 之后
  • [ 0, 1, 2, 4 ]//赋值后

在第二种情况下,它应该会触发某种内存访问冲突,因为会尝试写入数组中的第 5 个条目 (array[4]),当数组的长度只有 4 个条目。

我知道 NodeJS 可以应用一些内存管理方案,以某种方式允许它在没有“数组索引越界”异常的情况下完成,但我仍然不明白为什么它会让这个操作“逃脱”它”,此外,为什么结果是这样。

array[array.length - 1] = array.pop() 可能是未定义的行为吗?

JavaScript 中是否存在未定义的行为

最佳答案

The second option: The statement array.pop() is executed after the expression array.length - 1 is evaluated

这确实发生了。 JS 评估总是从左到右。它计算 array.length - 1 到数组的索引 4,然后从数组中弹出最后一个元素,然后将该元素分配给索引 4。

In the second case, it should have triggered some sort of memory-access violation, because there would be an attempt to write into the 5th entry in the array (array[4]), when the length of the array is only 4 entries.

没有,JS中没有内存访问冲突。它只是再次创建一个新属性,并相应地更改数组的长度。这与代码发生的情况相同

const array = [0, 1, 2, 3, 4];
const element = array.pop();
console.log(JSON.stringify(array)); // [0,1,2,3]
array[4] = element;
console.log(JSON.stringify(array)); // [0,1,2,3,4]

类似地,填充数组使用相同的特性:

const array = [];
for (let i=0; i<5; i++)
    array[i] = i; // no memory access violation
console.log(array.length); // 5

关于javascript - 'array[array.length - 1] = array.pop()' 会产生未定义的行为吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59068472/

相关文章:

php - PHP 关联数组是否有相当于 Python 字典 setdefault 的功能?

java - 为什么我无法在循环之外访问我的二维数组?

node.js - 巢.js | @Exclude() 装饰器在 POST 方法中不起作用

node.js - 如何从Node.js中内置的VSCode运行js文件?

javascript - 如何在 Javascript 中使用正则表达式捕获此模式?

javascript - 当子 firebase 和 javascript 发生变化时我想要键值

javascript - react : TypeError: Cannot read property 'setState' of undefined

javascript - 函数调用另一个函数但不等待返回值?

ios - Xcode 6 中的 Storyboard

javascript - 引用错误: Can't find variable with SpookyJS