1. 程式人生 > >ES6擴充套件運算子(...)

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]
  • 意義

    1. 替代函式的apply方法

      由於擴充套件運算子可以展開陣列,所以不再需要apply方法,將陣列轉為函式的引數了。

      // ES5 的寫法
      Math.max.apply(null, [14, 3, 77])
      // ES6 的寫法
      Math
      .max(...[14, 3, 77])
  • 應用

    1. 複製陣列

      // ES5 的寫法
      const a1 = [1, 2];
      const a2 = a1.concat();
      // ES6 的寫法
      const a1 = [1, 2];
      const a2 = [...a1];
      //或
      const [...a2] = a1;
    2. 合併陣列

      // ES5 的寫法
      [1, 2].concat(more);
      arr1.concat(arr2, arr3);
      // ES6 的寫法
      [1, 2, ...more];
      [...arr1, ...arr2, ...arr3]
    3. 與解構賦值結合

      // ES5 的寫法
      a = list[0], rest = list.slice(1
      ) // ES6 的寫法 [a, ...rest] = list

      注意:如果將擴充套件運算子用於陣列賦值,只能放在引數的最後一位,否則會報錯。

    4. 轉換字串

      擴充套件運算子還可以將字串轉為真正的陣列,並且能夠正確識別四個位元組的 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'
    5. 實現Iterator介面的物件

      任何 Iterator 介面的物件(參閱 Iterator 一章),都可以用擴充套件運算子轉為真正的陣列。

    6. 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 }

    注意:

    1. 由於解構賦值要求等號右邊是一個物件,所以如果等號右邊是undefinednull,就會報錯,因為它們無法轉為物件。

    2. 解構賦值必須是最後一個引數,否則會報錯。

    3. 解構賦值的拷貝是淺拷貝,即如果一個鍵的值是複合型別的值(陣列、物件、函式)、那麼解構賦值拷貝的是這個值的引用,而不是這個值的副本。

      let obj = { a: { b: 1 } };
      let { ...x } = obj;
      obj.a.b = 2;
      x.a.b // 2
    4. 擴充套件運算子的解構賦值,不能複製繼承自原型物件的屬性。

      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
  • 應用

    1. 擴充套件某個函式的引數,引入其他操作。

      function baseFunction({ a, b }) {
      // ...
      }
      function wrapperFunction({ x, y, ...restConfig }) {
      // 使用 x 和 y 引數進行操作
      // 其餘引數傳給原始函式
      return baseFunction(restConfig);
      }
    2. 取出引數物件的所有可遍歷屬性,拷貝到當前物件之中。

      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)
      )
    3. 合併兩個物件。

      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 });
    4. 修改現有物件部分的屬性。

      let newVersion = {
      ...previousVersion,
      name: 'New Name' // Override the name property
      };
    5. 其他

      • 如果把自定義屬性放在擴充套件運算子前面,就變成了設定新物件的預設屬性值。
      • 與陣列的擴充套件運算子一樣,物件的擴充套件運算子後面可以跟表示式。
      • 如果擴充套件運算子後面是一個空物件,則沒有任何效果。
      • 如果擴充套件運算子的引數是nullundefined,這兩個值會被忽略,不會報錯。
      • 擴充套件運算子的引數物件之中,如果有取值函式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