es6的三個點不是函數,而是一種運算子。三個點“...”指的是“擴展運算符”,可將可迭代對象展開到其單獨的元素中;所謂的可迭代對象就是任何能用for of循環進行遍歷的對象,例如數組、字串、Map、Set、DOM節點等。
本教學操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。
擴充運算子… 是ES6中引入的,將可迭代物件展開到其單獨的元素中,所謂的可迭代物件就是任何能用for of迴圈進行遍歷的對象,例如:數組(數組常用方法)、字串、Map (悟透Map)、Set (Set 如何使用?)、DOM節點等。
#擴充運算子(spread)是三個點(...
)。它好比 rest 參數的逆運算,將一個陣列轉為用逗號分隔的參數序列。擴展運算子與正常的函數參數可以結合使用,後面也可以放置表達式,但如果後面是空數組,則不會產生任何效果。
let arr = []; arr.push(...[1,2,3,4,5]); console.log(arr); //[1,2,3,4,5] console.log(1, ...[2, 3, 4], 5) //1 2 3 4 5 console.log(...(1 > 0 ? ['a'] : [])); //a console.log([...[], 1]); //[1]
意義
替代函數的apply方法
由於擴充運算子可以展開數組,所以不再需要apply
方法,將數組轉為函數的參數了。
// ES5 的写法 Math.max.apply(null, [14, 3, 77]) // ES6 的写法 Math.max(...[14, 3, 77])
應用程式
#複製陣列
// ES5 的写法 const a1 = [1, 2]; const a2 = a1.concat(); // ES6 的写法 const a1 = [1, 2]; const a2 = [...a1]; //或 const [...a2] = a1;
合併陣列
// ES5 的写法 [1, 2].concat(more); arr1.concat(arr2, arr3); // ES6 的写法 [1, 2, ...more]; [...arr1, ...arr2, ...arr3]
與解構賦值結合
// ES5 的写法 a = list[0], rest = list.slice(1) // ES6 的写法 [a, ...rest] = list
#注意:如果將擴充運算子用於陣列賦值,只能放在參數的最後一位,否則會報錯誤。
轉換字串
擴充運算子還可以將字串轉為真正的數組,並且能夠正確識別四個位元組的 Unicode 字元。
'x\uD83D\uDE80y'.length // 4 [...'x\uD83D\uDE80y'].length // 3 let str = 'x\uD83D\uDE80y'; str.split('').reverse().join('') // 'y\uDE80\uD83Dx' [...str].reverse().join('') // 'y\uD83D\uDE80x'
實作Iterator介面的物件
任何 Iterator 介面的物件(參閱 Iterator 章節),都可以用擴充運算子轉為真正的陣列。
Map和Set結構、Generator函數
let map = new Map([ [1, 'one'], [2, 'two'], [3, 'three'], ]); let arr = [...map.keys()]; // [1, 2, 3]
const go = function*(){ yield 1; yield 2; yield 3; }; [...go()] // [1, 2, 3]
概念
物件的解構賦值用來從一個物件取值,相當於將目標物件本身的所有可遍歷的(enumerable)、但尚未被讀取的屬性,指派到指定的物件上面。所有的鍵和它們的值,都會拷貝到新物件上面。
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; x // 1 y // 2 z // { a: 3, b: 4 }
注意:
由於解構賦值要求等號右邊是一個對象,所以如果等號右邊是undefined
或null
,就會報錯,因為它們無法轉為物件。
解構賦值必須是最後一個參數,否則會錯誤。
解構賦值的拷貝是淺拷貝,也就是如果一個鍵的值是複合型別的值(陣列、物件、函數)、那麼解構賦值拷貝的是這個值的引用,而不是這個值的副本。
let obj = { a: { b: 1 } }; let { ...x } = obj; obj.a.b = 2; x.a.b // 2
擴充運算子的解構賦值,不能複製繼承自原型物件的屬性。
let o1 = { a: 1 }; let o2 = { b: 2 }; o2.__proto__ = o1; let { ...o3 } = o2; o3 // { b: 2 } o3.a // undefined const o = Object.create({ x: 1, y: 2 }); o.z = 3; let { x, ...newObj } = o; let { y, z } = newObj; x // 1 y // undefined z // 3 let { x, ...{ y, z } } = o; // SyntaxError: ... must be followed by an identifier in declaration contexts
應用程式
#擴充某個函數的參數,引入其他運算。
function baseFunction({ a, b }) { // ... } function wrapperFunction({ x, y, ...restConfig }) { // 使用 x 和 y 参数进行操作 // 其余参数传给原始函数 return baseFunction(restConfig); }
取出參數物件的所有可遍歷屬性,拷貝到目前物件之中。
let z = { a: 3, b: 4 }; let n = { ...z }; n // { a: 3, b: 4 } let aClone = { ...a }; // 等同于 let aClone = Object.assign({}, a); //上面的例子只是拷贝了对象实例的属性,如果想完整克隆一个对象,还拷贝对象原型的属性,可以采用下面的写法。 // 写法一 const clone1 = Object.assign( Object.create(Object.getPrototypeOf(obj)), obj ); // 写法二 const clone2 = Object.create( Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj) )
合併兩個物件。
let ab = { ...a, ...b }; // 等同于 let ab = Object.assign({}, a, b); //如果用户自定义的属性,放在扩展运算符后面,则扩展运算符内部的同名属性会被覆盖掉。 let aWithOverrides = { ...a, x: 1, y: 2 }; // 等同于 let aWithOverrides = { ...a, ...{ x: 1, y: 2 } }; // 等同于 let x = 1, y = 2, aWithOverrides = { ...a, x, y }; // 等同于 let aWithOverrides = Object.assign({}, a, { x: 1, y: 2 });
修改現有物件部分的屬性。
let newVersion = { ...previousVersion, name: 'New Name' // Override the name property };
其他
null
或undefined
,這兩個值會被忽略,不會報錯。 擴充運算子的參數物件之中,如果有取值函數get
,這個函數是會執行的。
【相關推薦:javascript影片教學、程式設計影片】
#以上是es6的三個點是什麼函數的詳細內容。更多資訊請關注PHP中文網其他相關文章!