use*_*050 -3 javascript arrays
这两个作业之间有什么区别?
this.list.push(...response.data);
//vs
this.list = [].concat(this.list, response.data);Run Code Online (Sandbox Code Playgroud)
就内容而言,结果将是相同的。将包含在response.data遗嘱中的项目附加到this.list。
但是,使用时this.list.push(...response.data),列表保持不变,并且只是使用新项进行了扩展,因此就地修改了列表。任何对该列表的引用都会看到更改的发生。
使用[].concat(this.list, response.data),将创建一个新列表。此新列表是两个列表的串联,然后重新分配给this.list。因此,分配后this.list指向一个新列表。在这种情况下,对旧列表的任何引用都不会看到更改发生。
第一个例子:
this.list.push(...response.data);
Run Code Online (Sandbox Code Playgroud)
该示例使用更改数据push。这意味着该数组已更改到位。这被认为是“不纯的”,因为它不会返回新的对象-它会更改已经存在的数据。
第二个例子:
this.list = [].concat(this.list, response.data);
Run Code Online (Sandbox Code Playgroud)
本示例返回一个新的数组对象。这意味着它订阅了功能范式。之所以认为它是纯净的,是因为它不会更改现有的Array,而是会为此创建一个新数组。
现在,您可能会想:“ 这就是其他答案所说的! ”
你是对的。起初我只是要编写一个附录,但我想我也可以简洁地提供所有信息。答案的第一部分看起来像是在重复练习,因为它们是正确的,而且...嗯,您无法克服。但是, 这是他们错过的地方:
如果要向内看,concat您会发现该方法本身会检查Symbol.isConcatSpreadable是对还是错。这可能会使您相信,如果spreadable为true(在ArrayObjects中默认为true),则它们的执行方式相同。这根本不是真的。
虽然在内部spread operator利用元素@@iterator来组合数组/值,但Array.prototype.concat实际上是像for循环那样构建该方法,ae- i=0;i<len;i++;实际上,在组合数组时,实际上是从被调用数组中弹出第一个元素并执行使用时不必要的断言和测试spread。
好吧,这意味着如果您以某种方式调整迭代器并认为您要使用spread运算符将Array串联在一起,则上面的两个示例可能会产生截然不同的结果。结果将不是您期望的。
在下面可以很容易看出这一点:
this.list.push(...response.data);
Run Code Online (Sandbox Code Playgroud)
这也意味着,与该Array.prototype.concat方法不同,因为散布使用iterator和,并且迭代器可以手动提供/调整,并且迭代器可以异步 -这就concat为从未设计过的用途打开了潜力。
基本上,spread是一种更全面的与津贴的很多不同应用运营商,而concat简直是只是一个简单的“拿这个,并把它在那里 ”有spreadable检查,只是确定是否应该执行一个小的值的循环内是for循环较大,或者内部数组引用足够好。
我希望这能回答您的问题,并让您进一步了解操作以及幕后的实际情况!
编码愉快!