ES6擴充套件運算子(...)
在使用vuex的過程中,經常會碰到以下寫法:
...mapGetters('user',['classList','class','subjectList','termList'])
在不瞭解ES6的擴充套件運算子前,對這種寫法很迷惑,不懂...
的作用到底是什麼,於是通過《ECMAScript 6 入門》一書,學習了擴充套件運算子的相關知識。
陣列的擴充套件運算子
概念
擴充套件運算子(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
應用
複製陣列
// 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
注意:如果將擴充套件運算子用於陣列賦值,只能放在引數的最後一位,否則會報錯。
轉換字串
擴充套件運算子還可以將字串轉為真正的陣列,並且能夠正確識別四個位元組的 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函式
- 擴充套件運算子內部呼叫的是資料結構的 Iterator 介面,因此只要具有 Iterator 介面的物件,都可以使用擴充套件運算子,比如 Map 結構。
let map = new Map([ [1, 'one'], [2, 'two'], [3, 'three'], ]); let arr = [...map.keys()]; // [1, 2, 3]
- Generator 函式執行後,返回一個遍歷器物件,因此也可以使用擴充套件運算子。
const go = function*(){ yield 1; yield 2; yield 3; }; [...go()] // [1, 2, 3]
- 如果對沒有 Iterator 介面的物件,使用擴充套件運算子,將會報錯。
物件的擴充套件運算子
概念
物件的解構賦值用於從一個物件取值,相當於將目標物件自身的所有可遍歷的(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
,這個函式是會執行的。
相關推薦
ES6擴充套件運算子(...)
在使用vuex的過程中,經常會碰到以下寫法: ...mapGetters('user',['classList','class','subjectList','termList']) 在不瞭解E
記錄一下ES6擴充套件運算子(三點運算子)...的用法
該記錄源於segmentfaul網友的評論,特意感謝! ...運算子用於運算元組,有兩種層面 1. 第一個叫做 展開運算子(spread operator),作用是和字面意思一樣,就是把東西展開。可以用在array和object上都行。 比如: let a = [1,2,
擴充套件運算子(...)的用途
1.合併陣列 一直以來,有很多方法合併陣列,但是擴充套件運算子給了我們全新的方法去實現合併陣列: arr1.push(...arr2) // 把arr2合併到arr1的後面 arr1.unshift(...arr2) //把arr2合併到arr1的前面 如果你想在陣列內
關於擴充套件運算子(...)
開發十年,就只剩下這套架構體系了! >>>
es6 擴充套件運算子三個點(...)的用法及總結
不明白的: 1.0 apply() 2.0 合併陣列的幾種方法(Array.prototype.push.apply(arr1,arr2))//不理解 3.0 Iterator 介面的物件 4.0 Map 和 Set 結構, Generator 函式 1.0 含義 擴充
ES2015/ES6 擴充套件運算子 三個點(...)
1 含義 擴充套件運算子( spread )是三個點(...)。它好比 rest 引數的逆運算,將一個數組轉為用逗號分隔的引數序列。 console.log(...[1, 2, 3]) // 1 2 3 console.log(1, ...[2, 3, 4], 5)
es6 擴充套件運算子和rest運算子
物件擴充套件運算子(…): 當編寫一個方法時,我們允許它傳入的引數是不確定的。這時候可以使用物件擴充套件運算子來作引數,看一個簡單的列子: function leiy(...arg){ console.log(arg[0]); console.log(arg[1]); console.lo
小程式學習--ES6擴充套件運算子的用法
看下這段JS程式碼,請求到資料之後,在前端渲染頁面都是需要寫上字首, 比如我這個程式碼中的字首是classic,所以在渲染的時候,都需要寫上classic.欄位名 onLoad: function (options) { classicModel.getLatest((res)
ES6 擴充套件運算子的應用
(1)複製陣列 陣列是複合的資料型別,直接複製的話,只是複製了指向底層資料結構的指標,而不是克隆一個全新的陣列。 //複製陣列 const a1 = [1,2]; const a2 = a1; a2[0] = 3; console.log(a1)
異或運算子(^)
關於異或運算(^),談談自己淺顯的認識: 0異或任何非零數n結果為n,n^n=0。 交換律:a ^ b = b ^ a, 結合律:a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c, d = a ^ b ^ c 可以推出 a = d ^ b ^ c, 自反性:a ^
ES6學習筆記()
看網上一些ES6相關資料,來學習ES6,記錄下其間學習的筆記,以及一些疑惑,供後期自己方便查閱,未解決疑問以後懂了再加上…… ES6學習筆記(一)相關內容:作用域、let命令、const命令 一、作用域的概念 ES6之前,有 全域性作用域 和 函式作用域 到了E
ES6擴充套件運算子
擴充套件運算(spread) (1). 定義 擴充套件運算子(spread)是三個點(…)。它好比 rest 引數的逆運算,將一個數組轉為用逗號分隔的引數序列。主要用於函式的呼叫中。 function push(array, ...items) { array.pu
ES6中Set()的使用——javaScript
記錄一波今天在專案中實踐使用ES6中的Set()的資料結構,感覺特別帥氣!!! Set()可以實現在返回的一串資料的陣列中挑選出滿足你條件的資料。最大的關注點就是:去重!!! 使用場景:後臺返回一個
es6擴充套件運算子 三個點(...)
1 含義 擴充套件運算子( spread )是三個點(...)。它好比 rest 引數的逆運算,將一個數組轉為用逗號分隔的引數序列。 [javascript] view plain copy console.log(...[1, 2, 3]) /
es6之擴充套件運算子 三個點(...)
es6之擴充套件運算子 三個點(…) 物件的擴充套件運算子 理解物件的擴充套件運算子其實很簡單,只要記住一句話就可以: 物件中的擴充套件運算子(...)用於取出引數物件中的所有可遍歷屬性,拷貝到當前物件之中 let bar = { a: 1, b: 2 }
ES6躬行記(2)——擴充套件運算子和剩餘引數
擴充套件運算子(Spread Operator)和剩餘引數(Rest Parameter)的寫法相同,都是在變數或字面量之前加三個點(...),並且只能用於包含Symbol.iterator屬性的可迭代物件(iterable)。雖然兩者之間有諸多類似,但它們的功能和應用場景卻完全不同。擴充套件運算子能把整
ES6—陣列的擴充套件操作(擴充套件運算子)
一:擴充套件運算子 1:含義 擴充套件運算子(spread)是三個點(...)。它好比 rest 引數的逆運算,將一個陣列轉為用逗號分隔的引數序列。擴充套件運算子內部呼叫的是資料結構的 Iterator 介面 console.log(1, ...[2, 3, 4], 5)
從零開始學_JavaScript_系列(41)——物件的擴充套件(4)擴充套件運算子三個點...
0、一句話總結 屬性名,以及是屬性的函式的簡潔寫法,寫起來簡單易閱讀 屬性名可以用變數字串拼接起來(話說以前也有吧?) 函式都有name屬性,但set和get也要加字首 Object.is判斷兩個變數是否相等 Obje
ES6學習筆記(一)——字串的擴充套件
預備知識 utf-16:把Unicode字符集的抽象碼位對映為16位長的整數(即碼元)的序列,Unicode字元的碼位,需要1個或2個16位的碼元來表示。 utf-32:使用32個位元對每個Unicode碼位進行編碼,編碼長度是固定的,即32位。 js
ES6重點--筆記(轉)
ava 例如 ring func arrow tps 新建 方程 document 最常用的ES6特性 let, const, class, extends, super, arrow functions, template string, destructuring, d