Mozilla说:
map不会改变调用它的数组(尽管回调,如果被调用,可能会这样做).
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map
具体来说,回调传递的第三个参数是:
调用了数组映射.
我假设这意味着内存中的数组位置通过引用复制到回调中.
因此,通过改变第三个参数,我们应该改变原始数组,但是以下两个片段会产生相互矛盾的结果:
情况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 mutateRun Code Online (Sandbox Code Playgroud)
情况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) // [] mutatedRun Code Online (Sandbox Code Playgroud)
显然,在第二种情况下,原始数组是变异的(迭代器只执行一次).但是我错过了什么?为什么冲突的结果呢?
在案例1中,您只是重新分配 - 这与突变是分开的.只有你有类似的语法才会发生变异obj.prop = <someExpression>.这就是你在案例2中所做的事情
_B.length = 0;
Run Code Online (Sandbox Code Playgroud)
内存中_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);Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
71 次 |
| 最近记录: |