我了解concat
方法的工作原理,但是我对MDN docs中的一行有一个疑问。
它说:
concat
方法不会更改this
或作为参数提供的任何数组,而是返回一个浅表副本,其中包含与原始数组组合的相同元素的副本。
我的问题是,它有可能潜在地更改this
吗?是否表示参数数组可能会丢失其this
,但由于它只是创建一个新数组而保留了它?
答案 0 :(得分:5)
在调用a.concat(b, c)
中,被调用的函数为a.concat
, this 值为a
,自变量为b
和c
。 MDN所说的是,该调用不会更改数组a
,与a.push(x)
不同。
const arr = [1, 2, 3];
arr.concat([4, 5]);
console.log(arr.join(', '));
// the “this” array in the call `arr.concat([4, 5])` didn’t change
arr.push(6);
console.log(arr.join(', '));
// the “this” array in the call `arr.push(6)` changed
答案 1 :(得分:3)
某些函数 mutate 传递给它的参数,或改变其调用上下文。一个示例是.sort()
-如果您使用数组someArr
然后执行const result = someArr.sort()
,则result
和原始someArr
将被排序(它们将引用相同的对象)。
相反,concat
不会使任何传递的数组或其调用上下文发生突变。一个不了解JS的人可能会认为concat
向数组concat
添加项正在被调用,就像下面的代码一样:
Array.prototype.myConcat = function(...arrs) {
arrs.forEach((arr) => {
arr.forEach(item => {
this.push(item);
});
});
}
const orig = [1, 2, 3];
const another = [4, 5, 6];
orig.myConcat(another);
console.log(orig);
但这不是本地concat
函数的工作方式-它创建了一个全新数组,这是文档中要阐明的内容。
答案 2 :(得分:1)
当函数被调用为对象的方法(在此示例中为数组)时,this
设置为调用该方法的对象。我认为这是摆脱这一困境最重要的事情...
换句话说,文档只是在说concat
在其上被调用的原始对象不会被突变,因为它concat
创建了一个全新数组。因此,concat
是少数几个不会使this
突变的数组函数之一。如上所述,Array.sort
/ Array.push
确实会使调用它们的上下文发生变异。
不改变所调用上下文或在某些情况下更改其参数的函数是首选,因为它们不会引起任何副作用。它们也称为pure
函数,因为在给定输入的情况下,它们总是产生相同的输出,同时产生零副作用。
由于有一些优点,因此有一个名为lodash/fp的lodash的完整子集,专用于纯函数和函数编程的思想。还有Ramda等。
希望这会有所帮助。