传播语法与切片方法
spread syntax vs slice method
我试图通过以下方法了解扩展语法与切片方法之间的区别。
假设我想制作一个数组的实际副本,我可能可以使用展开语法轻松完成
var fruits = ["Banana", "Chips" , "Orange", "Lemon", "Apple", "Mango"]
var newCitrus = [...fruits]
如果我console.log这个
["Banana", "Chips", "Orange", "Lemon", "Apple", "Mango"]
但我也可以使用 slice 方法创建数组的副本。考虑到上面的相同数组,如果我做这样的事情...
var citrus = fruits.slice(0);
然后控制台记录它,它会给我完全相同的数组,我会通过传播语法得到这个数组
["Banana", "Chips", "Orange", "Lemon", "Apple", "Mango"]
因为两者到code/write的时间差不多,所以这里有什么区别?我通常应该选择哪种方法?
性能将取决于其运行所在的引擎。与大多数 Javscript 代码一样,在各种不同的引擎中它可能是 运行。所以,使用任何感觉美观的东西。对我来说,这是传播。
...
是纯粹的美。
如果您决定使用 slice,请跳过 0,只说 .slice()
。
撇开性能不谈 slice
只是 Array.prototype
上的一个函数,因此它仅适用于数组。另一方面,传播语法适用于任何可迭代对象(满足 iterable protocol) so it will work out of the box on any String
, Array
, TypedArray
, Map
and Set
. You can also easily create custom iterables.
slice
ing 和 spread
ing 带孔数组(稀疏数组)也有区别。正如您在下面看到的,slice
将保留稀疏性,而 spread
将用 undefined
.
填充空洞
Array(3) // produces sparse array: [empty × 3]
Array(3).slice() // produces [empty × 3]
[...Array(3)] // produces [undefined, undefined, undefined]
扩展语法也可用于制作对象的浅克隆:
const obj = { foo: 'bar', baz: 42 };
const clone = { ...obj };
obj.foo === clone.foo // true
obj.baz === clone.baz // true
obj === clone // false (references are different)
Measuring in Chrome 表明 slice 的性能远高于展开运算符,每秒 67M 次操作,而每秒 4M 次操作。如果您正在构建 Chrome 或 Electron 应用程序(使用 Chromium),我会选择切片,尤其是对于大数据和实时应用程序。
编辑:
似乎 Spread 运算符现在快得多,尽管仍然比 Slice 慢:
Chrome (72+) 的新版本似乎消除了性能差距。
https://measurethat.net/Benchmarks/ListResults/2667
虽然这两种方法实际上并不等同。 Slice 是 Array.prototype
上的一个函数,并且知道数组的实现。它将创建一个非常有效的副本。但更重要的是,.slice()
将保留数组的稀疏信息。
相比之下,[...Array]
只会从现有数组的可迭代视图创建一个新数组。不一定高效。
试试这个:
var a = [];
a.length = 3;
console.log("slice:", a.slice());
console.log("spread:", [...a]);
使用 Chrome 浏览器开发者控制台,我得到了这些结果:
slice: (3) [empty × 3]
spread: (3) [undefined, undefined, undefined]
如果你的数组特别大+稀疏,array.slice()
会特别快。 [...array]
可能会挂起您的浏览器。
我试图通过以下方法了解扩展语法与切片方法之间的区别。
假设我想制作一个数组的实际副本,我可能可以使用展开语法轻松完成
var fruits = ["Banana", "Chips" , "Orange", "Lemon", "Apple", "Mango"]
var newCitrus = [...fruits]
如果我console.log这个
["Banana", "Chips", "Orange", "Lemon", "Apple", "Mango"]
但我也可以使用 slice 方法创建数组的副本。考虑到上面的相同数组,如果我做这样的事情...
var citrus = fruits.slice(0);
然后控制台记录它,它会给我完全相同的数组,我会通过传播语法得到这个数组
["Banana", "Chips", "Orange", "Lemon", "Apple", "Mango"]
因为两者到code/write的时间差不多,所以这里有什么区别?我通常应该选择哪种方法?
性能将取决于其运行所在的引擎。与大多数 Javscript 代码一样,在各种不同的引擎中它可能是 运行。所以,使用任何感觉美观的东西。对我来说,这是传播。
...
是纯粹的美。
如果您决定使用 slice,请跳过 0,只说 .slice()
。
撇开性能不谈 slice
只是 Array.prototype
上的一个函数,因此它仅适用于数组。另一方面,传播语法适用于任何可迭代对象(满足 iterable protocol) so it will work out of the box on any String
, Array
, TypedArray
, Map
and Set
. You can also easily create custom iterables.
slice
ing 和 spread
ing 带孔数组(稀疏数组)也有区别。正如您在下面看到的,slice
将保留稀疏性,而 spread
将用 undefined
.
Array(3) // produces sparse array: [empty × 3]
Array(3).slice() // produces [empty × 3]
[...Array(3)] // produces [undefined, undefined, undefined]
扩展语法也可用于制作对象的浅克隆:
const obj = { foo: 'bar', baz: 42 };
const clone = { ...obj };
obj.foo === clone.foo // true
obj.baz === clone.baz // true
obj === clone // false (references are different)
Measuring in Chrome 表明 slice 的性能远高于展开运算符,每秒 67M 次操作,而每秒 4M 次操作。如果您正在构建 Chrome 或 Electron 应用程序(使用 Chromium),我会选择切片,尤其是对于大数据和实时应用程序。
编辑:
似乎 Spread 运算符现在快得多,尽管仍然比 Slice 慢:
Chrome (72+) 的新版本似乎消除了性能差距。 https://measurethat.net/Benchmarks/ListResults/2667
虽然这两种方法实际上并不等同。 Slice 是 Array.prototype
上的一个函数,并且知道数组的实现。它将创建一个非常有效的副本。但更重要的是,.slice()
将保留数组的稀疏信息。
相比之下,[...Array]
只会从现有数组的可迭代视图创建一个新数组。不一定高效。
试试这个:
var a = [];
a.length = 3;
console.log("slice:", a.slice());
console.log("spread:", [...a]);
使用 Chrome 浏览器开发者控制台,我得到了这些结果:
slice: (3) [empty × 3]
spread: (3) [undefined, undefined, undefined]
如果你的数组特别大+稀疏,array.slice()
会特别快。 [...array]
可能会挂起您的浏览器。