一篇文章搞懂ES6,真的不能再細了

2020-08-12 16:37:40

一、ECMAScript 相關介紹

1.1 什麼是ECMA

ECMA(European Computer Manufacturers Association)中文名稱爲歐洲計算機制 機製 造商協會,這個組織的目標是評估、開發和認可電信和計算機標準。1994 年後該 組織改名爲 Ecma 國際。

1.2 什麼是ECMAScript

ECMAScript 是由Ecma國際通過 ECMA-262標準化的指令碼程式設計語言。

1.3 什麼是ECMA-262

Ecma 國際制定了許多標準,而 ECMA-262 只是其中的一個。所有標準列表點我檢視

1.4 ECMA-262歷史

ECMA-262(ECMAScript)歷史版本點我檢視

版本 時間 說明
第1版 1997年 制定了語言的基本語法
第2版 1998年 較小改動
第3版 1999年 引入正則、例外處理、格式化輸出等,IE開始支援
第4版 2007年 過於激進,未發佈
第5版 2009年 引入嚴格模式、JSON,擴充套件物件、陣列、原型、字串、日期方法
第6版 2015年 模組化、物件導向語法、Promise、箭頭函數、let、const、陣列解構賦值等
第7版 2016年 冪運算子、陣列擴充套件、Async/await關鍵字
第8版 2017年 Async/swait、字串擴充套件
第9版 2018年 物件解構賦值、正則擴充套件
第10版 2019年 擴充套件物件陣列方法
ES.next 動態指向下一個版本

1.5 誰在維護ECMA-262

TC39(Technical Committee 39)是推進 ECMAScript發展的委員會。其會員都是 公司(其中主要是瀏覽器廠商,有蘋果、谷歌、微軟、因特爾等)。TC39定期 召開會議,會議由會員公司的代表與特邀專家出席

二、ES6新特性

2.1 let 關鍵字

let關鍵字用來宣告變數,使用let宣告的變數特點如下:

  • 不允許重複宣告
  • 塊級作用域
  • 不存在變數提升
  • 不影響作用域鏈

範例如下:

<script>
   // 1. 不允許重複宣告
   // let name = '旺財';
   // let name = '小強';

   // 2. 塊級作用域
   // 宣告的變數只能在塊內使用,if while for else
   // {
   //   let name2 = '羅志祥';
   //   console.log(name2);
   // }
   // console.log(name2);

   // 3. 不存在變數提升
   // console.log(song);
   // let song = '白色空間';

   // 4. 不影響作用域
   // {
   //   let girl = '周揚青';
   //   function test(){
   //     console.log(girl);
   //   }
   //   test();
   // }
 </script>

const 關鍵字

const關鍵字用來宣告常數,特點如下:

  • 宣告時必須賦初始值
  • 識別符號一般爲大寫
  • 不允許重複宣告
  • 值不允許修改
  • 塊級作用域

範例如下:

<script>
 const VALUE = 12;
 // VALUE = 13; 會報錯

 const person = {
   name:'wangcai',
   age:12
 }

 console.log(person);// {name: "wangcai", age: 12}
 person.name = '小強';// 不會報錯
 console.log(person);// {name: "小強", age: 12}
 person = {};// Uncaught TypeError: Assignment to constant variable
</script>

注意:物件屬性修改和陣列元素變化不會觸發const報錯

應用場景:

  • 宣告物件型別使用const
  • 非物件型別使用let

2.2 變數的解構賦值

ES6允許按照一定模式,從陣列和物件中提取值,對變數進行賦值,這稱爲解構賦值。

  • 陣列的解構賦值
  • 物件的解構賦值

範例如下:

<script>
   // 1. 陣列的解構賦值
   const names = ["張三", "李四", "王五"];
   let [zhang, li, wang] = names;
   console.log(zhang);
   console.log(li);
   console.log(wang);

   // 2. 物件的解構賦值
   const person = {
     name: "旺財",
     age: 12,
     eat: function () {
       console.log("我就知道吃");
     },
   };
   let { name, age, eat } = person;
   console.log(name);
   console.log(age);
   eat();

   // 3. 複雜解構賦值
   let tingfeng = {
     name: "謝霆鋒",
     age: 38,
     songs: ["忘情水", "北京歡迎你"],
     history: [
       {
         name: "謝小小",
       },
       {
         name: "謝大大",
       },
     ],
   };

   let {
     songs: [one, two],
     history: [first, second],
   } = tingfeng;
   console.log(one);
   console.log(history);
   console.log(second);
 </script>

注意:頻繁使用物件方法、陣列元素,就可以使用解構賦值

2.3 模板字串

模板字串(template string)是增強版的字串,用反引號(`)標識,特點如下:

  • 字串中可以出現換行符
  • 可以使用${xxx}形式輸出變數

範例如下:

<script>
  // 1. 宣告模板字串
  let str = `我也是一個字串哦`

  // 2. 內容中可以直接出現換行符
  let str2 = `<ul>
                <li>腎疼</li>
                <li>腰疼</li>
                <li>胸疼</li>
              </ul>`

  // 3. 變數拼接
  let name = '旺財'
  let out = `${name}是我的最愛哦`
  console.log(out);
</script>

注意:當遇到字串與變數拼接時使用模板字串

2.4 簡化物件寫法

ES6允許在大括號裏面,直接寫入變數和函數,作爲物件的屬性和方法。

範例如下:

<script>
  let name = '旺財'
  let change = function(){
    console.log('我們可以改變世界');
  }
  const person={
    name,
    change,
    eat(){
      console.log('我們還可以吃吃吃');
    }
  }
  console.log(person);
</script>

注意:物件簡寫形式簡化了程式碼,推薦以後使用簡寫

2.5 箭頭函數

ES6允許使用「箭頭」(=>)定義函數,注意點如下:

  • 如果形參只有一個,則小括號可以省略
  • 函數體如果只有一條語句,則花括號可以省略,函數的返回值爲該條語句的執行結果
  • 箭頭函數this指向宣告時所在作用域下this的值
  • 箭頭函數不能作爲建構函式範例化
  • 不能使用arguments

範例如下:

<script>
  //  1.通用寫法
  let fn = (agr1, arg2, arg3) => {
    return agr1 + arg2 + arg3;
  };
  let result = fn(1, 2, 3);
  console.log(result);
  // this是靜態的,始終指向函數宣告時所在作用域下的this的值
  function getName() {
    console.log(this.name);
  }
  let getName2 = () => {
    console.log(this.name);
  };
  // 設定window的name屬性
  window.name = "旺財";
  const person = {
    name: "小強",
  };
  // 直接呼叫
  getName(); // 旺財
  getName2(); // 旺財
  // call方法呼叫
  getName.call(person); //小強
  getName2.call(person); // 旺財

  // 2. 不能作爲建構函式範例化物件
  // let Dog= (name,age)=>{
  //   this.name = name
  //   this.age = age
  // }
  // let d = new Dog('旺財',12)
  // console.log(d);//Uncaught TypeError: Dog is not a constructor

  // 3. 不能使用arguments變數
  // let fn2 = () => {
  //   console.log(arguments);//Uncaught ReferenceError: arguments is not defined
  // };
  // fn2();

  // 4. 箭頭函數的簡寫
  // 1. 當形參只有一個參數時,可以省略小括號
  let add = (n) => {
    return n + n;
  };
  // 2. 當函數體只有一條語句的時候,此時return可以省略,且語句的執行結果就是函數的返回值
  let pow = (n) => n * n;
  console.log(pow(2));
</script>

2.6 函數參數預設值

ES6允許給函數參數賦值初始值。

範例如下:

<script>
  // 1. ES6允許給函數參數設定預設值,一般位置放最後
  function add(a, b, c = 10) {
    return a + b + c;
  }
  let result = add(1, 2, 3);
  console.log(result);
  // 2. 與解構賦值結合
  function connect({ host = "127.0.0.1", port, username, password }) {
    console.log(host);
    console.log(password);
  }
  connect({
    host: "localhost",
    port: "8080",
    username: "root",
    password: "root",
  });
</script>

2.7 rest參數

ES6引入rest參數,用於獲取函數的實參,用來代替arguments

範例如下:

<script>
  // ES5獲取實參方式
  function data(){
    console.log(arguments);
  }
  data('旺財','小強','大明')
  // ES6 rest參數
  function data2(...args){
    console.log(args);
  }
  data2('豬','鴨','魚') // ["豬", "鴨", "魚"]
</script>

注意:rest參數非常適合不定個數參數函數的場景

2.8 擴充套件運算子

「...」擴充套件運算子能將陣列轉換爲逗號分隔的「參數序列」。

範例如下:

<body>
 <div></div>
 <div></div>
 <div></div>
 <script>
   // ...擴充套件運算子能將一個數組轉換成以逗號分隔的參數序列
   const tfboys = ['易烊千璽','王源','黃曉明'] // => '易烊千璽','王源','黃曉明'
   function chunwan(){
     console.log(arguments);
   }
   chunwan(...tfboys)

   // 1. 陣列的合併
   const kuaizi = ['肖央','王太利']
   const fenghuang = ['曾毅','玲花']
   const zuixuanxiaopingguo = kuaizi.concat(fenghuang)
   console.log(zuixuanxiaopingguo);
   const zuixuanxiaopingguo2 = [...kuaizi,...fenghuang]
   console.log(zuixuanxiaopingguo2);

   // 2. 陣列的克隆
   const sanzhihua = ['E','G','M']
   const sanyecao = [...sanzhihua]
   console.log(sanyecao);

   // 3. 將僞陣列轉換爲真正的陣列
   const divs = document.querySelectorAll('div')
   console.log(divs);
   const divArr = [...divs]
   console.log(divArr);
 </script>
</body>

2.9 Symbol

2.9.1 入門

ES6引入了一種新的原始數據型別Symbol,表示獨一無二的值。他是javascript語言的第七種數據型別,是一種類似於字串的數據型別。

特點如下:

  • symbol的值是唯一的,用來解決命名衝突問題
  • symbol值不能與其他數據進行運算
  • symbol定義的物件屬性不能使用for...in回圈遍歷,但是可以使用Reflect.ownKeys來獲取物件的所有鍵名

注意:遇到唯一性的場景,要使用symbol

2.9.2 建立symbol

  • Symbol()
  • Symbol('xxx')
  • Symbol.fro('xxx')

範例如下:

<script>
   // 建立symbol
   let s = Symbol();
   console.log(s, typeof s); // 10-symbol基本使用.html:12 Symbol() "symbol"

   let s2 = Symbol("demo");
   let s3 = Symbol("demo");
   console.log(s2, s3, s2 === s3); // Symbol(demo) Symbol(demo) false

   let s4 = Symbol.for("test");
   let s5 = Symbol.for("test");
   console.log(s4 === s5); // true

   // 不能與其他數據進行計算
   // let result = s + 100
 </script>

2.9.3 物件新增symbol型別屬性

範例如下:

<script>
   let game = {};
   // 宣告一個物件
   let methods = {
     up: Symbol(),
     down: Symbol(),
   };

   game[methods.up] = function () {
     console.log("我可以快速上升");
   };
   game[methods.down] = function () {
     console.log("我可以快速下降");
   };
   console.log(game);
   // 新增symbol屬性2
   let youxi = {
     name: '狼人殺',
     [Symbol('say')]:function(){
       console.log('我可以發炎');
     },
     [Symbol('zibao')]:function(){
       console.log('我可以自爆');
     }
   }
   console.log(youxi);
 </script>

2.9.4 Symbol的內建屬性

除了定義自己使用的Symbol值意外,ES6還提供了11個內建的Symbol值,指向語言內部使用的方法,可以稱這些方法爲魔術方法,因爲他們會在特定的場景下自動執行。

方法 描述
Symbol.hasInstance 當其他物件使用 instanceof 運算子,判斷是否爲該對 象的範例時,會呼叫這個方法
Symbol.isConcatSpreadable 物件的 Symbol.isConcatSpreadable 屬性等於的是一個 布爾值,表示該物件用於 Array.prototype.concat()時, 是否可以展開。
Symbol.species 建立衍生物件時,會使用該屬性
Symbol.match 當執行 str.match(myObject) 時,如果該屬性存在,會 呼叫它,返回該方法的返回值。
Symbol.replace 當該物件被 str.replace(myObject)方法呼叫時,會返回 該方法的返回值
Symbol.search 當該物件被 str. search (myObject)方法呼叫時,會返回 該方法的返回值。
Symbol.split 當該物件被 str. split (myObject)方法呼叫時,會返回該 方法的返回值。
Symbol.iterator 物件進行 for…of 回圈時,會呼叫 Symbol.iterator 方法, 返回該物件的預設遍歷器
Symbol.toPrimitive 該物件被轉爲原始型別的值時,會呼叫這個方法,返回該物件對應的原始型別值。
Symbol.toStringTag 在該物件上面呼叫 toString 方法時,返回該方法的返 回值
Symbol.unscopables 該物件指定了使用with關鍵字時,哪些屬性會被with 環境排除。

2.10 迭代器

迭代器是一種機制 機製,他是一種介面,爲各種不同的數據結構提供統一的存取機制 機製。任何數據結構只要部署Iterator介面,就可以完成遍歷操作。

ES6創造了一種新的遍歷命名for..of回圈,Iterator介面主要供for..of消費。

原生具備Iterator介面的數據(可用for of遍歷):

  • Array
  • Arguments
  • Set
  • Map
  • String
  • TypedArray
  • NodeList

工作原理:

  • 建立一個指針物件,指向當前數據結構的起始位置
  • 第一次呼叫物件的額next方法,指針自動指向數據結構的第一個成員
  • 接下來不斷呼叫next方法,指針一直往後移動,直到指向最後一個成員
  • 每呼叫next方法返回一個包含value和done屬性的物件

注意: 需要自定義遍歷數據的時候,要想到迭代器

範例程式碼:

<script>
   const xiyou = ["豬八戒", "唐僧", "孫猴子", "沙僧"];
   for (let v of xiyou) {
     console.log(v);
   }
   // 自定義迭代器
   const banji = {
     name: "終結一班",
     students: ["小米", "三星", "華爲"],
     [Symbol.iterator]() {
       let index = 0;
       let _this = this;
       return {
         next: function () {
           if (index < _this.students.length) {
             const result = { value: _this.students[index], done: false };
             index++;
             return result;
           } else {
             return { value: undefined, done: true };
           }
         },
       };
     },
   };
   for(let stu of banji){
     console.log(stu);
   }
 </script>

2.11 生成器

2.11.1 簡介

生成器函數時ES6提供的一種非同步變成解決方案,語法行爲與傳統函數完全不同。

範例程式碼:

<script>
  // 生成器其實就是一種特殊的函數,非同步程式設計
  function* gen() {
    console.log("hello generator");

    yield "一隻沒有耳朵";
    yield "一隻沒有尾巴";
    yield "真奇怪 真奇怪";
  }

  let iterator = gen();
  console.log(iterator);
  console.log(iterator.next()); //{value: "一隻沒有耳朵", done: false}
  console.log(iterator.next()); //{value: "一隻沒有尾巴", done: false}
  console.log(iterator.next()); //{value: "真奇怪 真奇怪", done: false}
  console.log(iterator.next()); //{value: undefined, done: true}
  // 遍歷
  // for(let v of gen()){
  //   console.log(v);
  // }
</script>

2.11.2 生成器函數的參數傳遞

範例如下:

// 生成器傳參
 function* gen2(arg) {
   console.log(arg);// AAA
   let one = yield 111;
   console.log(one);// BBB
   let two = yield 222;
   console.log(two);//CCC
   let three = yield 333;
   console.log(three);//DDD
 }

 // 執行獲取迭代器物件
 let iterator2 = gen2('AAA')
 console.log(iterator2.next())
 // next方法可以傳入實參
 console.log(iterator2.next('BBB'));
 console.log(iterator2.next('CCC'));
 console.log(iterator2.next('DDD'));

2.11.3 生成器函數範例

範例一:

<script>
  // 需求 1S後控制檯輸出111,2S後輸出222,3S後輸出333
  function one() {
    setTimeout(() => {
      console.log("111");
      iterator3.next()
    }, 1000);
  }
  function two() {
    setTimeout(() => {
      console.log("222");
      iterator3.next()
    }, 2000);
  }
  function three() {
    setTimeout(() => {
      console.log("333");
      iterator3.next()
    }, 3000);
  }
  function* gen() {
    yield one();
    yield two();
    yield three();
  }
  let iterator3 = gen()
  iterator3.next()
</script>

範例二:

<script>
  // 模擬獲取 用戶數據->訂單數據->商品數據
  function getUser() {
    setTimeout(() => {
      console.log("用戶數據獲取成功");
      let data = "用戶數據";
      iterator4.next(data)
    }, 1000);
  }
  function getOrders() {
    setTimeout(() => {
      console.log("訂單數據獲取成功");
      let data = "訂單數據";
      iterator4.next(data)
    }, 1000);
  }
  function getGoods() {
    setTimeout(() => {
      console.log("商品數據獲取成功");
      let data = "商品數據";
      iterator4.next(data)
    }, 1000);
  }

  function* gen4() {
    let user = yield getUser();
    console.log(`user:${user}`);
    let orders = yield getOrders();
    console.log(`orders:${orders}`);
    let goods = yield getGoods();
    console.log(`goods:${goods}`);
  }

  let iterator4 = gen4();
  iterator4.next();
</script>

2.12 Promise

PromiseES6引入的非同步程式設計的新解決方案。語法上Promise是一個建構函式,用來封裝非同步操作並可以獲取其成功或失敗的結果。

範例:

<script>
  // 範例化Promise物件
  new Promise(function (resolve, reject) {
    setTimeout(() => {
      let data = "hello world";
      // resolve(data);
      reject('error')
    }, 1000);
  }).then(
    function (value) {// 成功回撥 resolve
      console.log(value);
    },
    function (reason) {// 失敗回撥 reject
      console.log(reason);
    }
  );
</script>

2.13 集合

2.13.1 Set

ES6提供了新的數據結構Set,類似於陣列,但成員的值都是唯一的,集合實現了iterator介面,所有可以使用「擴充套件運算子」「for...of...」進行遍歷,集合的屬性和方法如下:

  • size:返回集合的元素個數
  • add:增加一個新元素,返回當前集合
  • delete:刪除元素,返回boolean
  • has:檢測集閤中是否包含某個元素,返回boolean
  • clear:清空集合,返回undefined
<script>
  const s = newSet(["旺財", "小米", "三星", "華爲", "蘋果"]);
  console.log(s.size);
  s.add("諾基亞");
  s.delete("旺財");
  console.log(s.has("vivo"));
  s.clear();
  console.log(s);
  // 範例
  let arr = [1, 2, 1, 3, 5, 6, 2, 4, 5, 3];
  // 1. 陣列去重
  let r1 = [...new Set(arr)];
  console.log(r1);
  // 2. 陣列取交集
  let arr2 = [2, 3, 4, 2, 3, 9, 10];
  let r2 = [...new Set(arr)].filter((item) => new Set(arr2).has(item));
  console.log(r2);
  // 3. 並集
  let union = [...new Set([...arr, ...arr2])];
  console.log(union);
  // 4. 差集
  let r4 = [...new Set(arr)].filter((item) => !new Set(arr2).has(item));
  console.log(r4);
</script>

2.13.2 Map

ES6提供了Map數據結構,它類似於物件,也是鍵值對的集合。但是"鍵"的範圍不限於字串,各種型別的值(包括物件)都可以當做鍵。Map也實現了iterator介面,所以可以使用「擴充套件運算子」「for...of..」進行遍歷。Map的屬性和方法如下:

  • size:返回Map的元素個數
  • set:增加一個新元素,返回當前Map
  • get:返回鍵名物件的鍵值
  • has:檢測Map中是否包含某個元素,返回boolean
  • clear:清空集合,返回undefined

範例:

const m = new Map()
m.set('name','旺財')
m.set('change',function(){
  console.log('我是大旺財');
})
console.log(m.get('name'));
m.set('demo','test')
m.delete('demo')
for(let v of m){
  console.log(v);
}
m.clear()
console.log(m);

2.14 Class

ES6提供了更接近傳統語言的寫法,引入了Class(類)這個概念,作爲物件的模板。通過class關鍵字可以定義類。

基本上,ES6class可以看做只是一個語法糖,它的絕大部分功能,ES5都可以做到,新的class寫法只是讓物件原型的寫法更加清晰、更加物件導向程式設計的語法而已。

知識點:

  • class宣告類
  • constructor定義建構函式初始化
  • extends繼承父類別
  • super呼叫父級構造方法
  • static定義靜態方法和屬性
  • 父類別方法可以重寫

範例:

<script>
    // class初體驗
    class Phone {
      constructor(brand, price) {
        this.brand = brand;
        this.price = price;
      }

      call() {
        console.log("我可以打電話哦");
      }

      // get set方法
      get price() {
        console.log("get prices called");
        return 2999;
      }

      set price(newVal) {
        console.log("set price called");
      }

      // 靜態屬性
      static version = "MIUI 12.0.2";
      // 靜態方法
      static printVersion() {
        console.log("i am ", this.version);
      }
    }

    let huawei = new Phone("華爲", 1111);
    huawei.call();
    console.log(huawei.version); // undefined
    // huawei.printVersion()// Uncaught TypeError: huawei.printVersion is not a function
    console.log(Phone.version); // MIUI 12.0.2
    Phone.printVersion(); //i am  MIUI 12.0.2
    // get set test
    console.log(huawei.price);// 2999
    huawei.price = "3999";
    console.log(huawei.price);

    // 類繼承
    class SmartPhone extends Phone {
      constructor(brand, price, color, size) {
        super(brand, price);
        this.color = color;
        this.size = size;
      }
      photo() {
        console.log("我可以拍照哦");
      }
      // 子類重寫父類別方法
      call() {
        console.log("我可以視訊通話哦");
      }
    }

    let xiaomi = new SmartPhone("小米", 1999, "red", 6.9);
    xiaomi.photo(); // 我可以拍照哦
    xiaomi.call(); // 我可以視訊通話哦
  </script>
</body>

2.15 數值擴充套件

2.15.1 二進制和八進制

ES6提供了二進制和八進制數值的新的寫法,分別用字首0b0o表示。

 // 二進制和八進制
 let b = 0b1010;
 let o = 0o777;
 let d = 100;
 let x = 0xff;
 console.log(b, o, d, x);

2.15.2 isFinite和isNaN

  • Number.isFinite() 用來檢查一個數值是否是有限的
    -Number.isNaN()用來檢查一個值是否爲NaN

2.15.3 parseInt和parseFloat

ES6將全域性方法parseIntparseFloat移植到Number物件上面,使用不變

2.15.4 trunc

Math.trunc()用於去除一個小數的小數部分,返回整數部分

2.15.5 isInteger

Number.isInteger()用來判斷一個數值是否爲整數

2.15.6 範例

<script>
   // 二進制和八進制
   let b = 0b1010;
   let o = 0o777;
   let d = 100;
   let x = 0xff;
   console.log(b, o, d, x); //10 511 100 255
   // isFinite 檢測一個數值是否爲有限數
   console.log(Number.isFinite(100)); // true
   console.log(Number.isFinite(100 / 0)); // false
   console.log(Number.isFinite(Infinity)); // false
   // isNaN檢測一個數值是否爲NaN
   console.log(Number.isNaN(123)); // false
   // parseInt parseFloat字串轉整數
   console.log(Number.parseInt("123asa")); //123
   console.log(Number.parseFloat("2.3431ifm是")); //2.3431
   // isInteger判斷一個數是否爲整數
   console.log(Number.isInteger(5)); //true
   console.log(Number.isInteger(5.2)); //false
   // trunc將數位的小數部分抹掉
   console.log(Math.trunc(3.4)); //3
   // sign判斷一個梳到底爲整數 負數  還是零
   console.log(Math.sign(100)); //1
   console.log(Math.sign(0)); //0
   console.log(Math.sign(-100)); //-1
 </script>

2.16 物件擴充套件

ES6新增了一些Object物件的方法:

  • Object.is:比較兩個值是否嚴格相等,與「===」行爲基本一致(+0與NaN)
  • Object.assign:物件的合併,將源物件的所有可列舉屬性,複製到目標物件
  • __proto__setPrototypeOf可以直接設定物件的原型

範例:

<script>
   // 1. Object.is判斷兩個值是否完全相等
   console.log(Object.is(120, 120)); //true
   console.log(Object.is(NaN, NaN)); // true
   console.log(NaN === NaN); // false
   // 2. Object.assign物件的合併
   const config1 = {
     host: "localhost",
     port: "9090",
   };
   const config2 = {
     port: "8080",
     username: "username",
   };
   console.log(Object.assign(config1, config2)); //{host: "localhost", port: "8080", username: "username"} 同欄位的話後面會把前面的替換
   // 3, Object.setPrototypeof 設定物件原型
   const p = {
     name: "旺財",
   };
   const hobbis = {
     hobbies: ["籃球", "足球"],
   };
   Object.setPrototypeOf(p, hobbis);
   console.log(Object.getPrototypeOf(p)); //hobbies: (2) ["籃球", "足球"]  _proto__: Object
   console.log(p); //{name: "旺財"}name: "旺財"__proto__: hobbies: (2) ["籃球", "足球"]__proto__: Object
 </script>

2.17 模組化

模組化是指將一個大的程式檔案,拆分爲許多小的檔案,然後將小檔案組合起來。

2.17.1 好處

模組化的優勢有以下幾點:

  • 防止命名衝突
  • 程式碼複用
  • 高維護性

2.17.2 模組化規範產品

ES6之前的模組化規範有:

  • CommonJS ==> NodeJSBrowerify
  • AMD ===> requireJS
  • CMD ==> seaJS

2.17.3 ES6模組化語法

模組功能個主要由兩個命令構成:exportimport

  • export:用於規定模組的對外介面,導出
  • import:用於輸入其他模組提供的功能,匯入
  • 統一暴露
  • 分開暴露
  • 預設暴露