1. 程式人生 > >JS中的擴充套件運算子...

JS中的擴充套件運算子...

JS中的擴充套件運算子一般用於以下情況:

  1. 陣列和物件的深拷貝(僅限單層陣列或物件的深拷貝,實際上對於陣列和物件的巢狀來說還是淺拷貝)
let arr = ['a', 'b']
let arr1 = [...arr]
let [...arr2] = arr 
console.log(arr1, arr2) //輸出['a', 'b'] ['a', 'b']

這裡陣列arr和arr1和arr2儲存在不同的對記憶體地址中,互相之間不會產生任何影響。

  1. 陣列或物件的拼接
let arr = ['a', 'b']
let arr1 = ['c']
let arr2 = [...arr, ...arr1]
console.log(arr2) //輸出 ["a", "b", "c"]
  1. 函式傳參(解構賦值)
function add(...arr) {
	let sum = 0
	arr[0] = 11
	sum = arr.reduce((prev, cur) => {
		return prev + cur
	}, 0)
	return sum
}
let arr = [1, 2]
let sum = add(...arr)
console.log(sum) //得到的值是13
console.log(arr) //得到的值依然是[1,2]

我們知道,js中函式引數的傳遞時按值傳遞的,詳見我的另一篇文章

那麼這裡的傳參就不是簡單的賦值操作了,而是在堆記憶體中重新開闢了一塊空間來存放傳入的陣列,再將該塊記憶體中的地址傳遞給引數arr,其實這裡也就是深拷貝的意思。此時你對arr再做任何操作也影響不到外層的arr了。
在ES5中通過apply函式和bind+call函式也可以實現上述深拷貝傳參。

  • apply方式
let arr = [1,2]
function add(x, y) {
	x= 5
	let sum = 0
	sum = x + y
	return sum
}
let sum= add.apply(add, arr)
console.log(sum) // 輸出7
console.log(arr) //輸出 [1, 2]
  • bind + call 方式
let sum2 = add.bind(add,1,2).call()
console.log(sum2) //輸出7

當然,由於擴充套件運算子在傳參時可以對引數進行結構賦值,所以以上bind+call方法在傳參時可以改成如下:

 let sum2 = add.bind(add, ...arr).call()
 console.log(sum2) //輸出7

因此對於傳參時的結構賦值來說,我的理解是對部署了Symbol.iterator介面的資料型別進行解構。
可以將字串解構成陣列,將陣列解構成’用逗號分隔的引數序列

小技巧:

  • 陣列的push操作再也不用用迴圈啦
let arr1 = ['a', 'b']
let arr2 = ['c']
arr1.push(...arr2)
  • 求取陣列中的最大(小)值也可以直接使用Math.max啦
let arr = [1,2,3,4]
let max = Math.max(...arr)
  • 將字串轉化成陣列也很easy啦,不用藉助match函數了。
let str = 'abcde'
let arr = [...str]

以前用match函式的實現:

let arr = str.match(/\w/g)
  • 同時將其他部署了Symbol.iterator介面的物件轉化成陣列也更方便啦
var nodeList = document.querySelectorAll('div');  
var array = [...nodeList];  

參考:https://www.jianshu.com/p/86cbabeda999