Mozilla 说:
map does not mutate the array on which it is called (although callback, if invoked, may do so).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
具体来说,回调传递的第三个参数是:
The array map was called upon.
我假设这意味着内存中的数组位置通过引用复制到回调中。
因此,通过改变第三个参数,我们应该改变原始数组,但以下两段代码给出了冲突的结果:
情况 1,重新分配第三个参数并没有改变原始数组:
var A = [1, 2, 3];
A.map((v,i,_A) => {
console.log("_A is the array map invoked on: ", _A===A); // true
_A = []; // reassign an empty array
return v;
});
console.log("'A' did not mutate:", A) // [1, 2, 3] did not mutate
情况 2,将第三个参数的长度设置为零会改变原始数组:
var B = [1, 2, 3];
B.map((v,i,_B) => {
console.log("_B is the array map invoked on: ", _B===B); // true
_B.length = 0; // clearing the array by setting it zero length
return v;
});
console.log("'B' has mutated:", B) // [] mutated
很明显,在第二种情况下,原始数组发生了变化(迭代器只执行一次)。 但是我错过了什么?为什么会出现矛盾的结果?
最佳答案
在情况 1 中,您只是重新分配 - 这与突变不同。仅当您使用类似 obj.prop = <someExpression>
的语法时才会发生突变.这就是你在案例 2 中所做的
_B.length = 0;
内存中的对象 _B
引用文献将有其 .length
属性突变。但只是重新分配一个变量名,比如_A = []
,不会改变任何_A
碰巧之前引用了 - _A
之前引用的对象将被忽略(保持不变),并且将来引用 _A
在范围内将引用刚刚分配给 _A
的任何内容.
这实际上与Array.prototype.map
没有任何关系| - 这与您在任何 Javascript 对象或变量名中看到的行为相同,例如:
const obj = { foo: 'foo' };
let anotherObj = obj; // references the original object
anotherObj = {};
// a new object is created in memory and assigned to the variable name `anotherObj`
// but this does not mutate whatever anotherObj happened to refer to before
console.log(obj);
关于javascript - Array.prototype.map() 可以改变它调用的数组吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53808896/