简单的JS数组`concat`的说明

时间:2018-08-27 00:23:37

标签: javascript arrays this

我了解concat方法的工作原理,但是我对MDN docs中的一行有一个疑问。

它说:

  

concat方法不会更改this或作为参数提供的任何数组,而是返回一个浅表副本,其中包含与原始数组组合的相同元素的副本。


我的问题是,它有可能潜在地更改this吗?是否表示参数数组可能会丢失其this,但由于它只是创建一个新数组而保留了它?

3 个答案:

答案 0 :(得分:5)

在调用a.concat(b, c)中,被调用的函数为a.concat this 值为a,自变量为bc。 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等。

希望这会有所帮助。