【前端 JavaScript 高級(jí)】 05 - ES6 - ES11

1. ECMASript 相關(guān)介紹

1.1 什么是 ECMA

什么是ECMA
  1. ECMA(European Computer Manufacturers Association)中文名稱(chēng)為歐洲計(jì)算機(jī)制造商協(xié)會(huì)附井, 這個(gè)組織的目標(biāo)是評(píng)估、開(kāi)發(fā)和認(rèn)可電信和計(jì)算機(jī)標(biāo)準(zhǔn)盟猖。 1994 年后該組織改名為 Ecma 國(guó)際。

1.2 什么是 ECMAScript

  1. ECMAScript 是由 Ecma 國(guó)際通過(guò) ECMA-262 標(biāo)準(zhǔn)化的腳本程序設(shè)計(jì)語(yǔ)言。

1.3 什么是 ECMA-262

  1. Ecma 國(guó)際制定了許多標(biāo)準(zhǔn),而 ECMA-262 只是其中的一個(gè), 所有標(biāo)準(zhǔn)列表查看

1.4 ECMA-262 歷史

  1. ECMA-262(ECMAScript)歷史版本查看網(wǎng)址
版 本 時(shí) 間 事 項(xiàng)
第 1 版 1997 年 制定了語(yǔ)言的基本語(yǔ)法
第 2 版 1998 年 較小改動(dòng)
第 3 版 1999 年 引入正則醋拧、異常處理、格式化輸出等淀弹。 IE 開(kāi)始支持
第 4 版 2007 年 過(guò)于激進(jìn)趁仙,未發(fā)布
第 5 版 2009 年 引入嚴(yán)格模式、 JSON垦页,擴(kuò)展對(duì)象、數(shù)組干奢、原型痊焊、字符串、日期方法
第 6 版 2015 年 模塊化忿峻、面向?qū)ο笳Z(yǔ)法薄啥、Promise、箭頭函數(shù)逛尚、 let垄惧、const、數(shù)組解構(gòu)賦值等等
第 7 版 2016 年 冪運(yùn)算符绰寞、數(shù)組擴(kuò)展到逊、Async/await 關(guān)鍵字
第 8 版 2017 年 Async/await铣口、字符串?dāng)U展
第 9 版 2018 年 對(duì)象解構(gòu)賦值、正則擴(kuò)展
第 10 版 2019 年 擴(kuò)展對(duì)象觉壶、數(shù)組方法
ES.next 動(dòng)態(tài)指向下一個(gè)版本

注:從 ES6 開(kāi)始脑题,每年發(fā)布一個(gè)版本,版本號(hào)比年份最后一位大 1

1.5 誰(shuí)在維護(hù) ECMA-262

  1. TC39(Technical Committee 39) 是推進(jìn) ECMAScript 發(fā)展的委員會(huì)铜靶。其會(huì)員都是公司(其中主要是瀏覽器廠商叔遂,有蘋(píng)果、谷歌争剿、微軟已艰、因特爾等)。 TC39 定期召開(kāi)會(huì)議蚕苇,會(huì)議由會(huì)員公司的代表與特邀專(zhuān)家出席哩掺。

1.6 為什么要學(xué)習(xí) ES6

  1. ES6 的版本變動(dòng)內(nèi)容最多,具有里程碑意義;

  2. ES6 加入許多新的語(yǔ)法特性捆蜀,編程實(shí)現(xiàn)更簡(jiǎn)單疮丛、高效;

  3. ES6 是前端發(fā)展趨勢(shì),就業(yè)必備技能辆它。

1.7 ES6 兼容性

  1. 可查看兼容性誊薄;

2. ECMASript 6 新特性

2.1 let關(guān)鍵字

let 關(guān)鍵字用來(lái)聲明變量,使用 let 聲明的變量有幾個(gè)特點(diǎn):
  1. 不允許重復(fù)聲明變量;

  2. 有塊兒級(jí)作用域;

  3. 不存在變量提升(預(yù)解析)锰茉,如之前使用 var關(guān)鍵字聲明變量時(shí)會(huì)將使用 var 聲明 提到最前面呢蔫。var num = 10; 變量提升之后 是將 var num; 提到最前面之后在進(jìn)行賦值操作;

  4. 不影響作用域鏈。

應(yīng)用場(chǎng)景:以后聲明變量使用 let 就對(duì)了飒筑。

  let a;
  let b, c, d;
  let e = 100;
  let f = 222, g = 'love you', h = [];
  
  // 1. 變量不能重復(fù)聲明
  // let star = '李連杰';
  // let star = '吳京';

  // 2. 使用var聲明的變量是可以重復(fù)的
  // var star = '李連杰';
  // var star = '吳京';

  // 2. 塊級(jí)作用域全局 函數(shù)片吊,eval

  {
    let boy = 'lyp';
  }

  console.log(boy); // 這里是訪(fǎng)問(wèn)不到的


  // 3. 不存在變量提升

  var song = '666';

  // 4. 不影響作用域鏈
  {
    let school = '王者學(xué)院';

    function fun() {
      console.log(school);
    }
  }

2.2 const 關(guān)鍵字

const 關(guān)鍵字用來(lái)聲明常量,const 聲明有以下特點(diǎn):
  1. 聲明必須賦初始值;

  2. 標(biāo)識(shí)符一般為大寫(xiě);

  3. 不允許重復(fù)聲明;

  4. 值不允許修改;

  5. 塊兒級(jí)作用域协屡。

注意: 對(duì)象屬性修改和數(shù)組元素變化不會(huì)觸發(fā) const 錯(cuò)誤俏脊。 應(yīng)用場(chǎng)景:聲明對(duì)象類(lèi)型使用 const,非對(duì)象類(lèi)型聲明選擇 let肤晓。

  // 聲明常量
  const SCHOOL = '王者學(xué)院';

  // 1. 常量的聲明一定要初始化

  const A;

  // 2. 常量的值不能修改
  SCHOOL = '666';

  // 3. const 有塊級(jí)作用域
  {
    const UZI = '烏茲';
  }

  console.log(UZI);

  // 4. 一般常量標(biāo)識(shí)符需要大寫(xiě)

  // 5. 對(duì)于數(shù)組和對(duì)象的元素修改爷贫,不算對(duì)常量的修改,不會(huì)報(bào)錯(cuò)

  const TEAM = ['王大', '王二', '王三'];

  TEAM.push('王四');

2.3 變量的解構(gòu)賦值

  1. ES6 允許按照一定模式补憾,從數(shù)組和對(duì)象中提取值漫萄,對(duì)變量進(jìn)行賦值,這被稱(chēng)為解構(gòu)賦值盈匾。
  // ES6允許按照一定的模式從數(shù)組或者對(duì)象中進(jìn)行提取值腾务,對(duì)變量進(jìn)行賦值
  // 這就被稱(chēng)為解構(gòu)賦值
  // 1. 數(shù)組的解構(gòu)
  const F4 = ['宋小寶', '小沈陽(yáng)', '劉能', '趙四'];

  let [song, xiao, liu, zhao] = F4;
  console.log(song);
  console.log(xiao);
  console.log(liu);
  console.log(zhao);

  // 2. 對(duì)象的解構(gòu)
  const obj = {
    name: '趙本山',
    age: '66',
    xiaopin: function () {
      console.log('我會(huì)演小品');
    }
  }

  let {xiaopin} = obj;
  // 解構(gòu)之后直接調(diào)用
  xiaopin();

注意:頻繁使用對(duì)象方法、數(shù)組元素削饵,就可以使用解構(gòu)賦值形式岩瘦。

2.4 模板字符串

模板字符串(template string)是增強(qiáng)版的字符串未巫, 用反引號(hào)(`)標(biāo)識(shí),特點(diǎn):
  1. 字符串中可以出現(xiàn)換行符;

  2. 可以使用 ${xxx}形式輸出變量担钮。

  // ES6中引入新的聲明字符串的方式 ``   '' ""

  // 1. 聲明
  let str = `我是一個(gè)字符串`;
  console.log(str, typeof str);

  // 2. 使用模板字符串之后可以直接出現(xiàn)換行符
  let star = `
              <h1>張三</h1>
              <h1>李四</h1>
              <h1>王五</h1>
              <h1>趙六</h1>
            `;
  console.log(star);

  // 3. 模板字符串中的字符串拼接
  let lovest = '歡歡'
  let starest = `${lovest}是我最喜歡的人`;
  console.log(starest);

注意:當(dāng)遇到字符串與變量拼接的情況使用模板字符串橱赠。

2.5 簡(jiǎn)化對(duì)象寫(xiě)法

  1. ES6 允許在大括號(hào)里面,直接寫(xiě)入變量和函數(shù)箫津,作為對(duì)象的屬性和方法狭姨。這樣的書(shū)寫(xiě)更加簡(jiǎn)潔。
let name = '王者學(xué)院';
let slogon = '666';
let improve = function () {
    console.log('可以提高你的技能');
}
//屬性和方法簡(jiǎn)寫(xiě)
let atguigu = {
  name,
  slogon,
  improve,
  change() {
      console.log('可以改變你')
  }
};

注意:對(duì)象簡(jiǎn)寫(xiě)形式簡(jiǎn)化了代碼苏遥,所以以后用簡(jiǎn)寫(xiě)就對(duì)了饼拍。

2.6 箭頭函數(shù)

  1. ES6 中的箭頭函數(shù) ()=> 定義函數(shù)。
/*******************************************************************************************/
  // ES6中的箭頭函數(shù) ()=> 定義函數(shù)
  /**
   * 傳統(tǒng)的聲明函數(shù)的方式
   */
  let fn = function (a, b) {
    return a + b;
  };

  console.log(fn(12, 32));

  /**
   * 使用箭頭函數(shù)的方式聲明一個(gè)函數(shù)
   */
  let fun = (a, b) => {
    return a + b;
  };

  // 調(diào)用函數(shù)
  console.log(fun(1, 3));

  /*******************************************************************************************/

  /**
   * 箭頭函數(shù) 和 傳統(tǒng)函數(shù)聲明的區(qū)別
   *
   * 1. this是靜態(tài)的田炭。 this始終是指向函數(shù) 聲明時(shí) 所在作用域 的 this 的值 师抄。無(wú)論怎么改變其this都是不會(huì)改變的
   *
   */
  function getName() {
    console.log(this.name); //
  }

  let getNameTo = () => {
    console.log(this.name);//
  };

  // 設(shè)置 widow  對(duì)象的name屬性
  window.name = 'windowyo';
  const SCHOOL = {
    name: 'ATLYP'
  };

  // 使用call調(diào)用改變它的this指向
  getName.call(SCHOOL); // 調(diào)用傳統(tǒng)方式聲明的函數(shù)并改變其this指向  ATLYP  指向改變了
  getNameTo.call(SCHOOL); // 調(diào)用箭頭函數(shù)方式聲明的函數(shù)并改變其this指向 windowyo 指向未改變

  /*******************************************************************************************/

  /**
   * 箭頭函數(shù)不能作為構(gòu)造函數(shù)創(chuàng)建對(duì)象的
   * @param name
   * @param age
   * @constructor
   */
  let Person = (name, age) => {
    this.name = name;
    this.age = age;
  };
  // let p = new Person('張三', 23); // Person is not a constructor 箭頭函數(shù)聲明的構(gòu)造函數(shù)不能創(chuàng)建對(duì)象
  /*******************************************************************************************/

  /**
   * 箭頭函數(shù)中是不能使用arguments變量
   */
  function useArguments(a, b) {
    console.log(arguments);
  }

  useArguments(12, 34);

  let notArguments = (a, b) => {
    // console.log(arguments);
  }
  notArguments(23, 56); // arguments is not defined
  /*******************************************************************************************/

  /**
   * 箭頭函數(shù)的簡(jiǎn)寫(xiě)
   *
   *  1. 省略小括號(hào),當(dāng)形參有且只有一個(gè)的時(shí)候
   *
   *  2. 可以省略花括號(hào) 教硫, 當(dāng)代碼體中只有一條語(yǔ)句的時(shí)候叨吮,此時(shí)return也必須省略,而且函數(shù)的執(zhí)行結(jié)果就是函數(shù)的返回值
   */

    // 1. 省略小括號(hào)
  let add = n => {
      return n + n;
    };

  console.log(add(20)); // 40

  // 2. 省略花括號(hào)
  let pow = n => n * n;
  console.log(pow(20)); // 400
  /*******************************************************************************************/
箭頭函數(shù)的注意點(diǎn):
  1. 如果形參只有一個(gè)瞬矩,則小括號(hào)可以省略;

  2. 函數(shù)體如果只有一條語(yǔ)句茶鉴,則花括號(hào)可以省略,函數(shù)的返回值為該條語(yǔ)句的執(zhí)行結(jié)果;

  3. 箭頭函數(shù) this 指向聲明時(shí)所在作用域下 this 的值;;

  4. 箭頭函數(shù)不能作為構(gòu)造函數(shù)實(shí)例化;

  5. 不能使用 arguments 景用。

  6. 箭頭函數(shù)中this是靜態(tài)的涵叮。 this始終是指向函數(shù) 聲明時(shí) 所在作用域 的 this 的值 。無(wú)論怎么改變其this都是不會(huì)改變的伞插。

箭頭函數(shù)和實(shí)際的應(yīng)用場(chǎng)景
  1. 箭頭函數(shù)中this是靜態(tài)的割粮。 this始終是指向函數(shù) 聲明時(shí) 所在作用域 的 this 的值 。無(wú)論怎么改變其this都是不會(huì)改變的媚污。

  2. 箭頭函數(shù)適合與this無(wú)關(guān)的回調(diào)舀瓢、定時(shí)器、數(shù)組的方法回調(diào)耗美。

  3. 箭頭函數(shù)不適合與this有關(guān)的回調(diào)氢伟,如 事件回調(diào)、對(duì)象的方法幽歼。

// 獲取dom元素
  let ad = document.querySelector('.ad');

  /**
   * 箭頭函數(shù)不適合作為事件回調(diào) ,但是適合定時(shí)器谬盐,數(shù)組方法等
   */
  ad.addEventListener('click', function () {
    // 事先保存一個(gè) this
    let _this = this;
    // 在點(diǎn)擊盒子之后2秒改變盒子的顏色
    setTimeout(() => {
      // 注意這里的this 因?yàn)檫@里是一個(gè)箭頭函數(shù)甸私,箭頭函數(shù)中的this是靜態(tài)的,其是始終指向聲明時(shí)所在作用域的this的值
      // _this.style.backgroundColor = 'pink';
      this.style.backgroundColor = 'pink';
    }, 2000)
  });

  // 箭頭函數(shù)適合與 this 無(wú)關(guān)的回調(diào)飞傀、定時(shí)器皇型、數(shù)組的方法回調(diào)

  // 過(guò)濾數(shù)組中的元素诬烹,找出其中的偶數(shù)
  let arr = [1, 2, 3, 9, 90, 78];

  /**
   *
   * 使用傳統(tǒng)function聲明函數(shù)的方式
   * */
  let newArrFunction = arr.filter(function (item) {
    return item % 2 === 0;
  });
  console.log(newArrFunction);

  /**
   * 使用箭頭函數(shù)的方式
   * @type {number[]}
   */
  let newArr = arr.filter(item => item % 2 === 0);
  console.log(newArr);

  // 箭頭函數(shù)不適合與this有關(guān)的回調(diào),如事件回調(diào)弃鸦、對(duì)象的方法

注意:箭頭函數(shù)不會(huì)更改 this 指向绞吁,用來(lái)指定回調(diào)函數(shù)會(huì)非常合適。

2.7 rest 參數(shù)

  1. ES6 引入 rest 參數(shù)唬格,用于獲取函數(shù)的實(shí)參家破,用來(lái)代替 arguments
  // ES6引入rest參數(shù)用于獲取函數(shù)的實(shí)參购岗,用來(lái)代替arguments
  // ES5中獲取實(shí)參的方式
  function es5Arguments(a, b, c) {
    console.log(arguments); // 這是一個(gè)對(duì)象 {1, 2, 3}
  }

  es5Arguments(1, 2, 3);

  // ES6 中的rest參數(shù)
  /**
   * rest參數(shù)必須放在參數(shù)的最后
   */
  function es6Rest(a, b, ...args) {
    console.log(a);
    console.log(b);
    console.log(args); // 這是一個(gè)數(shù)組 [56, 89, 784, 12, 456, 456]
  }

  es6Rest(12, 23, 56, 89, 784, 12, 456, 456);

注意: rest 參數(shù)非常適合不定個(gè)數(shù)參數(shù)函數(shù)的場(chǎng)景汰聋。

ES6中函數(shù)參數(shù)的默認(rèn)值
  1. ES6中為形參賦初始值 , 具有默認(rèn)值的形參的位置一般靠后喊积。

  2. 參數(shù)默認(rèn)值可以與解構(gòu)賦值結(jié)合使用烹困。

  /**
   * ES6中為形參賦初始值 , 具有默認(rèn)值的形參的位置一般靠后
   * @param a
   * @param b
   * @param c
   */
  function add(a = 10, b = 20, c = 30) {
    return a + b + c;
  }


  // 2. 參數(shù)默認(rèn)值可以與解構(gòu)賦值結(jié)合使用
  function connect({host = '45.56.47.48', username = 'root', password = '123456', port = '3306'}) {
    console.log(host);
    console.log(username);
    console.log(password);
    console.log(port);
  }


  connect({
    host: '127.0.0.1',
    username: 'root',
    password: 'root',
    port: '3306'
  });

2.8 spread 擴(kuò)展運(yùn)算符

  1. 擴(kuò)展運(yùn)算符(spread)也是三個(gè)點(diǎn)(...)乾吻。它好比 rest 參數(shù)的逆運(yùn)算髓梅,將一個(gè)數(shù)組轉(zhuǎn)為用逗號(hào)分隔的參數(shù)序列,對(duì)數(shù)組進(jìn)行解包绎签。
 // 擴(kuò)展運(yùn)算符將數(shù)組轉(zhuǎn)換為逗號(hào)分隔的參數(shù)序列
  const tfBoy = ['易烊千璽', '王源', '張三'];

  function shaBi() {
    console.log(arguments);
  }
  shaBi(...tfBoy);
// 展開(kāi)運(yùn)算符 里面有引用數(shù)據(jù)類(lèi)型的話(huà)也是一個(gè)淺拷貝
  let oldArr = ['j', 'f', 'r', 'p'];

  let newArr = ['j', 'a', 'v', 'a'];

  newArr = oldArr.concat(newArr);

  console.log(newArr);

  let conCatArr = [...oldArr, ...newArr];
  console.log(conCatArr);

  // 將偽數(shù)組轉(zhuǎn)換為真正的數(shù)組
  let divs = document.querySelectorAll('div'); // 這是一個(gè)偽數(shù)組
  // 將偽數(shù)組轉(zhuǎn)換為真實(shí)的數(shù)組
  console.log(divs);
  let newDivs = [...divs];
  console.log(newDivs);

2.9 Symbol

Symbol 基本使用
  1. ES6 引入了一種新的原始數(shù)據(jù)類(lèi)型Symbol枯饿,表示獨(dú)一無(wú)二的值。它是JavaScript 語(yǔ)言的第七種數(shù)據(jù)類(lèi)型辜御,是一種類(lèi)似于字符串的數(shù)據(jù)類(lèi)型鸭你。
JavaScript 的七種數(shù)據(jù)類(lèi)型
  1. u undefined

  2. s string symbol擒权。

  3. o Object袱巨。

  4. n null number

  5. b boolean碳抄。

Symbol 特點(diǎn)
  1. Symbol 的值是唯一的愉老,用來(lái)解決命名沖突的問(wèn)題。

  2. Symbol 值不能與其他數(shù)據(jù)進(jìn)行運(yùn)算剖效。

  3. Symbol 定義 的 對(duì)象屬 性 不能 使 用for…in循 環(huán)遍 歷 嫉入,但 是可 以使用Reflect.ownKeys 來(lái)獲取對(duì)象的所有鍵名。

// 向?qū)ο笾刑砑訉傩院头椒?up down
  let game = {
    name: '張三',
    up: function () {
      console.log('我是up');
    },
    down: function () {
      console.log('我是down');
    }
  };

  let methods = {
    up: Symbol(),
    down: Symbol()
  };

  game[methods.up] = function () {
    console.log('我可以向上');
  };

  game[methods.down] = function () {
    console.log('我可以向下');
  };

  console.log(game);

/****************************************************************************************/
  // 第二種方式

  let obj = {
    name: '張三',
    up: function () {
      console.log('上');
    },
    [Symbol('say')]: function () {
      console.log('說(shuō)話(huà)');
    },
    [Symbol('sing')]: function () {
      console.log('唱歌');
    }
  }

  console.log(obj);

注: 遇到唯一性的場(chǎng)景時(shí)要想到 Symbol璧尸。

Symbol 內(nèi)置值
  1. 除了定義自己使用的 Symbol值以外是牢,ES6 還提供了 11 個(gè)內(nèi)置的 Symbol 值俱病,指向語(yǔ)言?xún)?nèi)部使用的方法。 可以稱(chēng)這些方法為魔術(shù)方法,因?yàn)樗鼈儠?huì)在特定的場(chǎng)景下自動(dòng)執(zhí)行合呐。
名稱(chēng) 作用
Symbol.hasInstance 當(dāng)其他對(duì)象使用 instanceof 運(yùn)算符唉韭,判斷是否為該對(duì)象的實(shí)例時(shí),會(huì)調(diào)用這個(gè)方法
Symbol.isConcatSpreadable 對(duì)象的 Symbol.isConcatSpreadable 屬性等于的是一個(gè)布爾值,表示該對(duì)象用于Array.prototype.concat()時(shí)活烙,是否可以展開(kāi)。
Symbol.species 創(chuàng)建衍生對(duì)象時(shí)遣鼓,會(huì)使用該屬性
Symbol.match 當(dāng)執(zhí)行 str.match(myObject)時(shí)啸盏,如果該屬性存在,會(huì)調(diào)用它骑祟,返回該方法的返回值回懦。
Symbol.replace 當(dāng)該對(duì)象被 str.replace(myObject)方法調(diào)用時(shí),會(huì)返回該方法的返回值曾我。
Symbol.search 當(dāng)該對(duì)象被str. search (myObject)方法調(diào)用時(shí)粉怕,會(huì)返回該方法的返回值。
Symbol.split 當(dāng)該對(duì)象被 str. split (myObject)方法調(diào)用時(shí)抒巢,會(huì)返回該方法的返回值贫贝。
Symbol.iterator 對(duì)象進(jìn)行for...of循環(huán)時(shí),會(huì)調(diào)用 Symbol.iterator方法蛉谜,返回該對(duì)象的默認(rèn)遍歷器
Symbol.toPrimitive 該對(duì)象被轉(zhuǎn)為原始類(lèi)型的值時(shí)稚晚,會(huì)調(diào)用這個(gè)方法,返回該對(duì)象對(duì)應(yīng)的原始類(lèi)型值型诚。
Symbol. toStringTag 在該對(duì)象上面調(diào)用toString 方法時(shí)客燕,返回該方法的返回值
Symbol. unscopables 該對(duì)象指定了使用with關(guān)鍵字時(shí),哪些屬性會(huì)被with 環(huán)境排除狰贯。
  1. 使用Symbol.isConcatSpreadable設(shè)置數(shù)組是否可以進(jìn)行拆解也搓。
  // Symbol 內(nèi)置了 11 個(gè)屬性
  // [Symbol.hasInstance]
  class Person {
    static [Symbol.hasInstance](param) {
      console.log(param);
      console.log('我是用來(lái)檢測(cè)類(lèi)型的');
      // 根據(jù)return 返回確定 false 或者 true
    }
  }

  let obj = {};

  console.log(obj instanceof Person);

  // 數(shù)組是否拆解合并
  let oldArr = [1, 2, 3, 4];
  let newArr = [4, 5, 6, 7];
  newArr[Symbol.isConcatSpreadable] = false; // 設(shè)置是否拆解進(jìn)行連接
  newArr = oldArr.concat(newArr);
  console.log(newArr);

2.10 迭代器

  1. 遍歷器(Iterator)就是一種機(jī)制。它是一種接口涵紊,為各種不同的數(shù)據(jù)結(jié)構(gòu)提供統(tǒng)一的訪(fǎng)問(wèn)機(jī)制傍妒。任何數(shù)據(jù)結(jié)構(gòu)只要部署 Iterator 接口,就可以完成遍歷操作摸柄。

  2. ES6創(chuàng)造了一種新的遍歷命令 for...of循環(huán)颤练,Iterator接口主要供for...of 消費(fèi)。

  3. 原生具備 iterator 接口的數(shù)據(jù)(可用 for of 遍歷)驱负。

Array
Arguments
Set
Map
String
TypedArray
NodeList

工作原理
  1. 創(chuàng)建一個(gè)指針對(duì)象嗦玖,指向當(dāng)前數(shù)據(jù)結(jié)構(gòu)的起始位置;

  2. 第一次調(diào)用對(duì)象的 next 方法,指針自動(dòng)指向數(shù)據(jù)結(jié)構(gòu)的第一個(gè)成員;

  3. 接下來(lái)不斷調(diào)用 next方法跃脊,指針一直往后移動(dòng)宇挫,直到指向最后一個(gè)成員;

  4. 每調(diào)用 next方法返回一個(gè)包含 valuedone屬性的對(duì)象。

自定義遍歷數(shù)據(jù)
// 聲明一個(gè)對(duì)象
  const banji = {
    name: '終極一班',

    stu: [
      'zhansgan',
      'lisi',
      'wangwu',
      'zhaoliu'
    ],
    /**
     *
     * 重寫(xiě)迭代器遍歷對(duì)象中的數(shù)組
     * */
    [Symbol.iterator]() {
      let index = 0;

      // 保存 this
      let _this = this;

      return {
        next: function () {
          if (index < _this.stu.length) {
            // 這是迭代器中返回的結(jié)果想
            let result = {value: _this.stu[index], done: false};
            index++;
            return result;
          } else {
            return {value: undefined, done: true};
          }
        }
      }

    }
  };

  /**
   * 使用for ... of ... 遍歷
   */
  for (let item of banji) {
    console.log(item);
  }

2.11 生成器

  1. 生成器函數(shù)是ES6 提供的一種異步編程解決方案酪术,語(yǔ)法行為與傳統(tǒng)函數(shù)完全不同器瘪。
 // 生成器是一個(gè)函數(shù) 是一個(gè)異步的編程解決方案
  // 異步編程使用的是純回調(diào)函數(shù)
  // yield 是函數(shù)代碼的分割符
  function* gen() {
    console.log('hello generator');
    console.log('111');
    yield '你是小豬豬';
    console.log('222');
    yield '你的小尾巴';
    console.log('333');
    yield '我你';
    console.log('444');
  }

  let iterator = gen();

  console.log(iterator);

  // 調(diào)用生成器函數(shù)
  // console.log(iterator.next());
  // console.log(iterator.next());
  // console.log(iterator.next());
  // console.log(iterator.next());

  // 可以使用 for...of... 進(jìn)行遍歷
  for (let item of gen()) {
    console.log(item);
  }
代碼說(shuō)明:
  1. * 的位置沒(méi)有限制;

  2. 生成器函數(shù)返回的結(jié)果是迭代器對(duì)象,調(diào)用迭代器對(duì)象的 next 方法可以得到yield 語(yǔ)句后的值;

  3. yield相當(dāng)于函數(shù)的暫停標(biāo)記娱局,也可以認(rèn)為是函數(shù)的分隔符,每調(diào)用一次 next方法咧七,執(zhí)行一段代碼;

  4. next 方法可以傳遞實(shí)參衰齐,作為 yield 語(yǔ)句的返回值。

生成器函數(shù)的參數(shù)
 /**
   * 生成器函數(shù)
   * @param arg
   */
  function* gen(arg) {
    console.log(arg); // 666
    let one = yield '1111';
    console.log(one); // 第一個(gè)參數(shù)
    let two = yield '2222';
    console.log(two); // 第二個(gè)參數(shù)
    let three = yield '3333';
    console.log(three); // 第三個(gè)參數(shù)
  }

  // next中可以傳遞參數(shù),參數(shù)將作為yield的返回值返回继阻。
  let iterator = gen('666');
  iterator.next();
  iterator.next('第一個(gè)參數(shù)');
  iterator.next('第二個(gè)參數(shù)');
  iterator.next('第三個(gè)參數(shù)');
案例 :1s 以后在控制臺(tái)輸出 111 耻涛, 2s之后輸出 222 3s之后輸出333
1s111 00_00_00-00_00_30.gif
  1. 傳統(tǒng)的定時(shí)器嵌套調(diào)用的方式 :容易形成回調(diào)地獄
  // 下面這是回調(diào)地獄
  setTimeout(() => {
    console.log(111);
    setTimeout(() => {
      console.log(222);
      setTimeout(() => {
        console.log(333);
      }, 3000);
    }, 2000);
  }, 1000);
  1. 使用生成器函數(shù)解決回調(diào)地獄問(wèn)題
/**
   * 使用生成器函數(shù)解決回調(diào)地獄問(wèn)題
   */
  function one() {
    setTimeout(() => {
      console.log('444');
      // 執(zhí)行完成調(diào)用下一次
      iterator.next();
    }, 1000);
  }


  function two() {
    setTimeout(() => {
      console.log('555');
      // 執(zhí)行完成調(diào)用下一次
      iterator.next();
    }, 2000);
  }

  function three() {
    setTimeout(() => {
      console.log('666');
      // 執(zhí)行完成調(diào)用下一次
      iterator.next();
    }, 3000);
  }

  let iterator = gen();

  /**
   * 生成器函數(shù)
   */
  function* gen() {
    yield one();

    yield two();

    yield three();
  }

  iterator.next();
案例 :分時(shí)段(先后)請(qǐng)求數(shù)據(jù) ,先請(qǐng)求用戶(hù)數(shù)據(jù)瘟檩,在請(qǐng)求訂單數(shù)據(jù)抹缕,最后請(qǐng)求商品數(shù)據(jù)
異步獲取數(shù)據(jù) 00_00_00-00_00_30.gif
function getUsers() {
    setTimeout(() => {
      let data = '用戶(hù)數(shù)據(jù)';
      iterator.next(data); // 通過(guò)next 將參數(shù)傳遞過(guò)去
    }, 1000);
  }

  function getOrders() {
    setTimeout(() => {
      let data = '訂單數(shù)據(jù)';
      iterator.next(data);
    }, 1000);
  }

  function getGoods() {
    setTimeout(() => {
      let data = '商品數(shù)據(jù)';
      iterator.next(data);
    }, 1000);
  }

  /**
   * 生成器函數(shù)
   */
  function* gen() {
    // 接收第二個(gè)next傳遞過(guò)來(lái)的參數(shù)
    let user = yield getUsers();
    console.log(user);

    let order = yield getOrders();
    console.log(order);

    let good = yield getGoods();
    console.log(good);
  }

  let iterator = gen();
  // 第一次調(diào)用
  iterator.next();

2.12 Promise

  1. Promise 是 ES6 引入的異步編程的新解決方案。語(yǔ)法上 Promise 是一個(gè)構(gòu)造函數(shù)墨辛,用來(lái)封裝異步操作并可以獲取其成功或失敗的結(jié)果卓研。
Promise 解決回調(diào)地獄問(wèn)題
  /**
   * promise解決回調(diào)地獄的問(wèn)題
   * @type {Promise<any>}
   */
    // 實(shí)例化 Promise的對(duì)象
  const p = new Promise(function (resolve, reject) {
      setTimeout(function () {
        /*// 成功的情況
        let data = '數(shù)據(jù)庫(kù)中的用戶(hù)數(shù)據(jù)';
        // resolve 調(diào)用它代表成功
        resolve(data);*/
        /*************************************************************/
        /*// 失敗的情況*/
        let error = '獲取數(shù)據(jù)庫(kù)數(shù)據(jù)失敗';
        reject(error); // reject 代表失敗
      }, 5000);
    });

  // 調(diào)用promise對(duì)象的then方法
  p.then(function (value) {
    // 成功
    console.log(value);
  }, function (reason) {
    // 失敗
    console.error(reason);
  });
Promise + Node 實(shí)現(xiàn)簡(jiǎn)單的文件讀取
  1. 使用傳統(tǒng)的方式 :
//1. 引入fs模塊
const fs = require('fs'); // 需要node環(huán)境的支持

// 2. 調(diào)用方法讀取文件
/**
 * 讀取文件內(nèi)容 data中是一個(gè)· buffer
 */
fs.readFile('../resources/666.md', (error, data) => {
  // 如果失敗將會(huì)拋出異常
  if (error) {
    throw error;
  }
  console.log(data.toString());
});
  1. 使用Promise的方式 :
//1. 引入fs模塊
const fs = require('fs'); // 需要node環(huán)境的支持
// 3. 使用 promise 修改讀取文件的操作
const p = new Promise(function (resolve, reject) {
  fs.readFile('../resources/666.md', (err, data) => {
    if (err) {
      // reject 是拒絕的意思
      reject(err);
    }
    // resolve 是解決的意思
    resolve(data);
  })
});
p.then(function (value) {
  console.log(value.toString());
}, function (reason) {
  console.log(reason);
});
使用Promise發(fā)送一個(gè)Ajax請(qǐng)求
  1. 如果有一種情況是需要先發(fā)送一個(gè)請(qǐng)求之后再發(fā)送另一個(gè)請(qǐng)求,如果請(qǐng)求多的情況下可能出現(xiàn)回調(diào)地獄的情況睹簇。
const p = new Promise((resolve, reject) => {
  // 1. 創(chuàng)建一個(gè)對(duì)象
  const xhr = new XMLHttpRequest();
// 2. 初始化
  xhr.open('GET', 'url');
// 3. 發(fā)送
  xhr.send();
// 4. 綁定事件
  xhr.onreadystatechange = function () {
    // 判斷
    if (xhr.readyState === 4) {
      // 判斷狀態(tài)碼 處于 200 - 299 之間
      if (xhr.status >= 200 && xhr.status <= 299) {
        // 表示成功
        // console.log(xhr.response);
        // 表示成功
        resolve(xhr.response);
      } else {
        // console.log(xhr.status);
        reject(xhr.status);
      }
    }
  };
});

/**
 * 使用then處理結(jié)果奏赘,解決回調(diào)地獄的問(wèn)題
 */
p.then((value) => {
  console.log(value);
}, (reason) => {
  console.log(reason);
})
Promise.prototype.then 調(diào)用then方法then方法的返回結(jié)果是 Promise對(duì)象,對(duì)象狀態(tài)由回調(diào)函數(shù)的執(zhí)行結(jié)果決定太惠。
  1. 如果回調(diào)函數(shù)中返回的結(jié)果是非Promise 類(lèi)型的屬性狀態(tài)為成功磨淌,返回值為對(duì)象成功的值。

  2. 如果沒(méi)有return返回結(jié)果凿渊,也是一個(gè)非Promise對(duì)象 梁只,此時(shí)Promise類(lèi)型屬性狀態(tài)為成功。

  3. 如果回調(diào)函數(shù)中返回的結(jié)果是一個(gè)Promise類(lèi)型的對(duì)象埃脏。

  4. 如果拋出錯(cuò)誤也是失敗的Promise的錯(cuò)誤搪锣。

 const p = new Promise((resolve, reject) => {
   setTimeout(() => {
     resolve('用戶(hù)數(shù)據(jù)');
   }, 1000)
});
 const result = p.then((value) => {
    console.log(value);
    // return 123; // fulfilled 是完成的意思
    // 如果拋出異常
    // throw new Error('發(fā)生了錯(cuò)誤'); // rejected
    // 如果回調(diào)函數(shù)中返回的是一個(gè) Promise 對(duì)象
    return new Promise((resolve, reject) => {
      resolve('解決'); // fulfilled
    });
  }, reason => {
    console.log(reason);
  });

 console.log(result);
Promise.prototype.catch 方法類(lèi)似一個(gè)語(yǔ)法糖
 const p = new Promise(
    (resolve, reject) => {
      setTimeout(() => {
        reject('出錯(cuò)了!');
      }, 1000)
    }
  );

  /**
   * catch類(lèi)似一個(gè)語(yǔ)法糖
   */
  p.catch((reason) => {
    console.warn(reason);
  });

2.13 Set

  1. ES6 提供了新的數(shù)據(jù)結(jié)構(gòu)Set(集合) 。它類(lèi)似于數(shù)組剂癌,但成員的值都是唯一的淤翔,集合實(shí)現(xiàn)了iterator 接口,所以可以使用『擴(kuò)展運(yùn)算符』和『for…of…』進(jìn)行遍歷佩谷,集合的屬性和方法:
  1. size 返回集合的元素個(gè)數(shù);
  2. add 增加一個(gè)新元素旁壮,返回當(dāng)前集合;
  3. delete 刪除元素,返回 boolean 值;
  4. has 檢測(cè)集合中是否包含某個(gè)元素谐檀,返回 boolean 值;
  5. clear 清空集合抡谐,返回undefined
  let s = new Set();
  console.log(typeof s);
  let s2 = new Set(['張三', '李四', '王五', '趙六']);
  console.log(s2.size);// 4
  // add
  s2.add('田七');
  console.log(s2); //
  // delete
  s2.delete('張三');
  // has
  console.log(s2.has('田七')); // true
  // clear
  // s2.clear();
  console.log(s2);
  // Set集合實(shí)現(xiàn)了 iterator 接口
  // 打印集合
  for (let item of s2) {
    console.log(item); // 李四 王五 趙六 田七
  }
Set 集合實(shí)踐:數(shù)組去重 + 求交集桐猬、并集麦撵、差集
  1. 交集:兩個(gè)數(shù)組中同時(shí)擁有的元素。

  2. 并集:在數(shù)組一中有,在數(shù)組二中也有免胃。

  3. 差集:求數(shù)組一和數(shù)組二的差集音五。在數(shù)組一中存在,但是在數(shù)組二中不存在的元素羔沙。

 let arr = [1,2,3,4,5,4,3,2,1];
  // 1. 數(shù)組去重
  let result = [...new Set(arr)]; // 元素唯一的數(shù)組
  console.log(result); // [1,2,3,4,5]
  // 2. 交集躺涝,在數(shù)組1 和數(shù)組2 中同時(shí)存在的元素
  let array = [1,2,6,8,9,5,4];
  // 首先將數(shù)組轉(zhuǎn)換為一個(gè)集合再判斷 arr 中的元素是否在 array 中存在
  let publicRes = arr.filter(item => new Set(array).has(item));
  // 將得到的數(shù)組通過(guò)集合去重
  console.log([...new Set(publicRes)]);// 去重 [1,2,4,5]
  // 3. 并集 在數(shù)組1中有在數(shù)組2中也有
  let union = [...new Set([...array, ...arr])];
  console.log(union); // [1,2,6,8,9,5,4,3]
  // 4. 差集 arr 中存在的元素在 array 中不存在的
  let diff = array.filter(item => !(new Set(arr).has(item)));
  console.log(diff); // [6,8,9]
集合與數(shù)組之間的轉(zhuǎn)換
 let oldArr = [3,2,1,5,6,89,5];
  // 數(shù)組轉(zhuǎn)集合
  let oldSet = new Set(oldArr);
  console.log(oldSet); // {3, 2, 1, 5, 6, 89,5}
  // 集合轉(zhuǎn)數(shù)組
  let newArr = [...oldSet];
  console.log(newArr); // [3, 2, 1, 5, 6, 89]

2.14 Map

  1. ES6 提供了 Map 數(shù)據(jù)結(jié)構(gòu)。它類(lèi)似于對(duì)象扼雏,也是鍵值對(duì)的集合坚嗜。 但是“鍵”的范圍不限于字符串,各種類(lèi)型的值(包括對(duì)象)都可以當(dāng)作鍵诗充。 Map 也實(shí)現(xiàn)了iterator 接口苍蔬,所以可以使用『擴(kuò)展運(yùn)算符』和『for…of…』進(jìn)行遍歷。 Map 的屬性和方法:
  1. size 返回 Map 的元素個(gè)數(shù);
  2. set 增加一個(gè)新元素蝴蜓,返回當(dāng)前 Map;
  3. get 返回鍵名對(duì)象的鍵值;
  4. has 檢測(cè) Map 中是否包含某個(gè)元素碟绑,返回boolean 值;
  5. clear 清空集合,返回 undefined;
  // 聲明Map
  let m = new Map();

  // 添加元素
  m.set('name', '仙桃');

  m.set('change', function () {
    console.log('我發(fā)生了改變');
  });

  // 鍵是一個(gè)對(duì)象
  let key = {
    school: 'XT'
  };

  m.set(key, ['張三', '李四', '王五']);

  // size
  console.log(m.size); // 3

  // 刪除
  m.delete('name');

  console.log(m); //
  // 獲取
  console.log(m.get(key)); // ['張三','李四','王五']
  console.log(m.get('change')); // f() {console.log('我發(fā)生了改變');}

  // 清空
  m.clear();

  console.log(m); // Map(0)

2.15 class 類(lèi)

  1. ES6 提供了更接近傳統(tǒng)語(yǔ)言的寫(xiě)法励翼,引入了 Class(類(lèi))這個(gè)概念蜈敢,作為對(duì)象的模板。通過(guò) class 關(guān)鍵字汽抚,可以定義類(lèi)抓狭。基本上造烁, ES6 的 class 可以看作只是一個(gè)語(yǔ)法糖否过,它的絕大部分功能, ES5 都可以做到惭蟋,新的 class 寫(xiě)法只是讓對(duì)象原型的寫(xiě)法更加清晰苗桂、更像面向?qū)ο缶幊痰恼Z(yǔ)法而已。
知識(shí)點(diǎn):
  1. class 聲明類(lèi);

  2. constructor 定義構(gòu)造函數(shù)初始化;

  3. extends 繼承父類(lèi);

  4. super 調(diào)用父級(jí)構(gòu)造方法;

  5. static 定義靜態(tài)方法和屬性;

  6. 父類(lèi)方法可以重寫(xiě)告组。

  // 手機(jī)類(lèi)
  function Phone(brand, price) {
    this.brand = brand;
    this.price = price;
  }

  // 添加方法 煤伟, 使用原型對(duì)象添加實(shí)現(xiàn)共享
  Phone.prototype.call = function () {
    console.log('我可以打電話(huà)');
  }

  // 實(shí)例化對(duì)象
  let huawei = new Phone('榮耀', 3999);

  huawei.call();
  console.log(huawei);


  class Ps5 {
    constructor(brand, price) {
      this.brand = brand;
      this.price = price;
    }

    play() {
      console.log('我可以打游戲');
    }
  }

  // 創(chuàng)建對(duì)象實(shí)例
  let ps = new Ps5('任天堂',2999);
  ps.play();
  console.log(ps);
類(lèi)里面的靜態(tài)成員
  /**
   * 在ES5中*************************************************
   */
  function Phone() {

  }

  Phone.name = '我是靜態(tài)成員'; // 屬于函數(shù)對(duì)象的 不屬于實(shí)例對(duì)象 為靜態(tài)成員
  Phone.change = function () {
    console.log('我可以改變世界');
  }; // 屬于函數(shù)對(duì)象的 不屬于實(shí)例對(duì)象 為靜態(tài)成員
  let nokia = new Phone();
  console.log(nokia.name); // undefined
  Phone.prototype.size = '5.5';
  console.log(nokia.size);

  /**
   * 在ES6中************************************************
   */
  class Person {
    // 在類(lèi)中聲明一個(gè)靜態(tài)成員
    static name = '王五';
    age = 23;
  }

  console.log(Person.name);
  console.log(Person.age); // undefined
  let p = new Person();

  console.log(p.age);
  console.log(p.name); // undefined
ES5中實(shí)現(xiàn)繼承
  /**
   * ES5中實(shí)現(xiàn)類(lèi)的繼承
   */
  function Phone(brand, price) {
    this.brand = brand;
    this.price = price;
  }

  function OnePlus(brand, price, color, size) {
    Phone.call(this, brand, price);
    this.color = color;
    this.size = size;
  }

  // 設(shè)置子級(jí)構(gòu)造函數(shù)的原型
  OnePlus.prototype = new Phone();
  OnePlus.prototype.constructor = OnePlus;

  // 聲明子類(lèi)方法
  OnePlus.prototype.photo = function () {
    console.log('我可以打電話(huà)');
  }

  OnePlus.prototype.playGame = function () {
    console.log('我可以玩游戲');
  }

  // 創(chuàng)建onPlus 實(shí)例
  let onePlus = new OnePlus('1+', 2999, '紅色', 5.5);
  console.log(onePlus);
  onePlus.photo();
  onePlus.playGame();

  // 原型對(duì)象 和 對(duì)象原型
  console.log(OnePlus.prototype);
  console.log(onePlus);
ES6 中類(lèi)的繼承
  1. 也可以對(duì)繼承的方法進(jìn)行重寫(xiě),但是在重寫(xiě)的方法中不能通過(guò)super關(guān)鍵字調(diào)用父類(lèi)的該方法木缝。
class Phone {
    constructor(brand, price) {
      this.brand = brand;
      this.price = price;
    }

    call() {
      console.log('我可以打電話(huà)');
    }

  }

  class OnePlus extends Phone {

    /**
     * 構(gòu)造函數(shù)
     */
    constructor(brand, price, color, size) {
      super(brand, price); // Phone(this,brand,price);
      this.color = color;
      this.size = size;
    }

    photo() {
      console.log('拍照');
    }

    playGame() {
      console.log('玩游戲');
    }
  }

  let onePLus = new OnePlus('1+', 3999, '綠色', 6.6);
  onePLus.photo(); // 拍照
  onePLus.playGame(); // 玩游戲
  onePLus.call(); // 我可以打電話(huà)
setter 和 getter 方法
 // get 和 set
  class Phone {
    get price() {
      console.log('獲取價(jià)格');
      return '2999';
    }

    set price(newValue) {
      console.log('價(jià)格被修改了');
    }
  }

  let s = new Phone();
  console.log(s.price);
  s.price = '3999';
  console.log(s.price);

2.16 ES6中數(shù)值的擴(kuò)展

二進(jìn)制和八進(jìn)制
  1. ES6 提供了二進(jìn)制和八進(jìn)制數(shù)值的新的寫(xiě)法便锨,分別用前綴 0b 和 0o 表示。
Number.isFinite() 與 Number.isNaN()
  1. Number.isFinite() 用來(lái)檢查一個(gè)數(shù)值是否為有限的我碟;
  1. Number.isNaN() 用來(lái)檢查一個(gè)值是否為 NaN放案。
Number.parseInt() 與 Number.parseFloat()
  1. ES6 將全局方法 parseInt 和 parseFloat,移植到 Number 對(duì)象上面矫俺,使用不變吱殉。
Math.trunc
  1. 用于去除一個(gè)數(shù)的小數(shù)部分掸冤,返回整數(shù)部分。
Math.sign
  1. 判斷一個(gè)數(shù)到底是 正數(shù) 還是負(fù)數(shù) 還是零友雳。正數(shù)返回 1 稿湿,負(fù)數(shù)返回 -1 零返回 0
代碼演示
// 1. Number.EPSILON 是JavaScript表示的最小精度
  console.log((0.1 + 0.2)); // 0.30000000000000004

  // 2. 二進(jìn)制和八進(jìn)制

  // 二進(jìn)制
  let b = 0b0101;
  console.log(b); // 5

  // 八進(jìn)制
  let o = 0o777;
  console.log(o); // 511

  // 十進(jìn)制
  let d = 10106;
  console.log(d); // 10106

  // 十六進(jìn)制
  let x = 0xfff;
  console.log(x);// 4095

  // 3. Number.isFinite() 檢測(cè)一個(gè)數(shù)值是否是一個(gè)有限數(shù)
  console.log(Number.isFinite(10)); // true
  console.log(Number.isFinite(100 / 0)); // false
  console.log(Number.isFinite(Infinity)); // false

  // 4. Number.isNaN() 檢測(cè)一個(gè)數(shù)值是否為NaN
  console.log(Number.isNaN(123));// false
  console.log(Number.isNaN(Number.parseInt('kk456')));// true

  // 5. Number.parseInt Number.parseFloat字符串轉(zhuǎn)整數(shù)或者浮點(diǎn)數(shù)
  let str = '123456';
  console.log(str); // 黑色字符串
  let num = Number.parseFloat(str);
  console.log(num);// 藍(lán)色數(shù)字

  str = 'kk456';
  num = Number.parseInt(str);
  console.log(num);

  // 6. Number.isInteger 判斷一個(gè)數(shù)是否為整數(shù)
  let intNum = 123;
  console.log(Number.isInteger(intNum)); // true

  // 7. Math.trunc() 將數(shù)字的小數(shù)部分抹掉
  let floatNum = 123.365;
  console.log(Math.trunc(floatNum)); // 123

  // 8. Math.sign 判斷一個(gè)數(shù)到底是 正數(shù) 還是負(fù)數(shù) 還是零
  console.log(Math.sign(10)); // 1
  console.log(Math.sign(0)); // 0
  console.log(Math.sign(-10)); // -1
Number.isInteger
  1. Number.isInteger() 用來(lái)判斷一個(gè)數(shù)值是否為整數(shù)。

2.17 對(duì)象擴(kuò)展

ES6 新增了一些 Object 對(duì)象的方法
  1. Object.is 比較兩個(gè)值是否嚴(yán)格相等押赊,與『===』行為基本一致(+0 與 NaN); 在其他情況下的比較情況下NaN和誰(shuí)比較都是false缎罢。但是在這里 NaNNaN 比較就是true

  2. Object.assign 對(duì)象的合并考杉,將源對(duì)象的所有可枚舉屬性,復(fù)制到目標(biāo)對(duì)象;

  3. __proto__舰始、 setPrototypeOf崇棠、 setPrototypeOf 可以直接設(shè)置對(duì)象的原型。

// 1. Object.is 判斷兩個(gè)值是否完全相等
  console.log(Object.is(120, 120)); // true
  console.log(Object.is(NaN, NaN)); // true
  console.log((NaN === NaN));// false
  // NaN 不管和誰(shuí)使用 === 做比較都是false

  // 2.Object.assign 對(duì)象合并
  const configA = {
    driver: 'jdbc.mysql.DataManagerDriver',
    url: 'localhost',
    username: 'root',
    password: 'root',
    test: 'test'
  };

  const configB = {
    driver: 'jdbc.mysql.DataManagerDriver',
    url: '127.0.0.1',
    username: 'admin',
    password: '12345'
  }
  console.log(Object.assign(configA, configB));
  console.log(configA);// 已經(jīng)合并
  console.log(Object.assign(configB, configA));

  // 3. 設(shè)置原型對(duì)象 Object.setPrototypeOf = 設(shè)置原型對(duì)象
  const school = {
    school: '仙桃大數(shù)據(jù)學(xué)院'
  };

  const area = {
    area: '渝北'
  };

  Object.setPrototypeOf(school, area);

  console.log(school);

  // 4. 獲取原型 Object.getPrototypeOf = 獲取原型對(duì)象
  console.log(Object.getPrototypeOf(school));

2.18 模塊化

  1. 模塊化是指將一個(gè)大的程序文件丸卷,拆分成許多小的文件枕稀,然后將小文件組合起來(lái)。
模塊化的好處
  1. 防止命名沖突谜嫉;

  2. 代碼復(fù)用萎坷;

  3. 高維護(hù)性。

模塊化規(guī)范產(chǎn)品
ES6 之前的模塊化規(guī)范有:
  1. CommonJS => NodeJS沐兰、 Browserify哆档;

  2. AMD => requireJS

  3. CMD => seaJS住闯。

ES6 模塊化語(yǔ)法
模塊功能主要由兩個(gè)命令構(gòu)成: exportimport 瓜浸。
  1. export 命令用于規(guī)定模塊的對(duì)外接口;

  2. import 命令用于輸入其他模塊提供的功能比原。

export的三種暴露方式
(一) export 分別暴露的方式
/**
 * 下面的屬于分別暴露
 * @type {string}
 */
export let school = '仙桃大數(shù)據(jù)學(xué)院';

export function teach() {
  console.log('傳授大數(shù)據(jù)開(kāi)發(fā)經(jīng)驗(yàn)');
}
(二)export統(tǒng)一暴露的方式
/**
 * 統(tǒng)一暴露
 * @type {string}
 */
let school = '仙桃大數(shù)據(jù)學(xué)校';

function stuData() {
  console.log('學(xué)習(xí)大數(shù)據(jù)');
}

/**
 * 統(tǒng)一暴露
 */
export {
  school,
  stuData
}
(三)export 默認(rèn)暴露的方式
export default {
  school:'仙桃大數(shù)據(jù)學(xué)院',
  change:function () {
    console.log('為技術(shù)而改變');
  }
}
import 的三種引入方式
(一) 使用解構(gòu)賦值的方式引入
 // m1
  import {school,teach} from '../js/m1.js';
  console.log(school);
  teach();
(二) 如果變量中出現(xiàn)了變量名重復(fù)的情況使用as進(jìn)行重命名
// m2
  import {school as xt,stuData} from '../js/m2.js';

  console.log(xt);
  stuData();
(三) 導(dǎo)入默認(rèn)暴露方式有兩種方式
// m3 導(dǎo)入默認(rèn)暴露
  import {default as m3} from '../js/m3.js';

  console.log(m3);

  // 簡(jiǎn)寫(xiě)形式只針對(duì)默認(rèn)暴露
  import m3Default from '../js/m3.js';
  console.log(m3Default);
  m3Default.change();
瀏覽器中使用模塊化的方式
  1. 將模塊的引入統(tǒng)一寫(xiě)到一個(gè)JS文件中 app.js插佛。
// 入口文件

// 模塊引入
import * as m1 from '../js/m1.js';
import * as m2 from '../js/m2.js';
import * as m3 from '../js/m3.js';
  1. 在頁(yè)面文件引入,app.js并將script的類(lèi)型設(shè)置為module量窘。
<!--類(lèi)型需要設(shè)置成module-->
<script  src="../js/app.js" type="module"></script>
ES6 中使用babel對(duì)ES6模塊化代碼進(jìn)行轉(zhuǎn)換使其通用
步驟
  1. 安裝工具:babel-cli 雇寇、 babel-preset-env (預(yù)設(shè)包)、browserify (webpack)(打包工具)蚌铜。

  2. 使用該安裝命令 : npm i babel-cli babel-preset-env browserify -D 進(jìn)行安裝锨侯。

  3. 執(zhí)行babel 命令(非全局安裝使用npx): npx babel js -d dist/js --presets=babel-preset-env

  4. 打包: npx browserify dist/js/app.js -o dist/bundle.js厘线。

ES6模塊化規(guī)范和NPM包的使用
  1. 使用npm 命令安裝 jquery: npm i jquery ;

3. ES7 新特性

3.1 Array.prototype.includes

  1. Includes 方法用來(lái)檢測(cè)數(shù)組中是否包含某個(gè)元素识腿,返回布爾類(lèi)型值。和原來(lái)數(shù)組中的 indexOf() 方法進(jìn)行區(qū)分造壮。indexOf() 返回的值是元素的位置渡讼,而includes方法返回的是true 或者false骂束。
 // includes
  const four = ['西游記','紅樓夢(mèng)','三國(guó)演義','水滸傳'];

  // 判斷
  console.log(four.includes('西游記')); // true
  console.log(four.includes('金畫(huà)畫(huà)')); // false

  // indexOf
  console.log(four.indexOf('西游記')); // 0
  console.log(four.indexOf('水滸傳')); // 3
  console.log(four.indexOf('金畫(huà)畫(huà)')); // -1

3.2 指數(shù)操作符(冪運(yùn)算)

  1. ES7 中引入指數(shù)運(yùn)算符「**」,用來(lái)實(shí)現(xiàn)冪運(yùn)算成箫,功能與Math.pow 結(jié)果相同如210展箱。
// 冪運(yùn)算 **
  console.log((2 ** 10)); // 1024
  console.log(Math.pow(2, 10)); // 1024

4. ECMASript 8 新特性

4.1 async 和 await

  1. asyncawait兩種語(yǔ)法結(jié)合可以讓異步代碼像同步代碼一樣。
async 函數(shù)
  1. async 函數(shù)的返回值為promise 對(duì)象蹬昌;

  2. promise 對(duì)象的結(jié)果由async 函數(shù)執(zhí)行的返回值決定混驰。

/**
   * async(異步的) 修飾的函數(shù)返回的是一個(gè) promise 對(duì)象
   *  1. 返回的結(jié)果不是一個(gè)Promise類(lèi)型的對(duì)象 就是一個(gè)成功的Promise;
   *  2. 拋出錯(cuò)誤 返回的結(jié)果是一個(gè)失敗的Promise;
   *  3. 如果返回的結(jié)果是一個(gè)Promise對(duì)象 ;
   */
  async function fun() {
    // 1. 返回的結(jié)果不是一個(gè)Promise對(duì)象
    // return '我是字符串';

    // 2. 返回的結(jié)果中拋出異常
    // throw new Error('這是一個(gè)錯(cuò)誤!');

    // 3. 返回的結(jié)果是一個(gè)Promise對(duì)象
    return new Promise((resolve, reject) => {
      // resolve('成功!');
      reject('拒絕!');
    })
  }
  const result = fun();
  console.log(result);
  /**
   * 處理結(jié)果
   */
  result.then(
    value => {
      console.log(value);
    },
    reason => {
      console.log(reason);
    });

4.2 await 表達(dá)式

  1. await 必須寫(xiě)在 async 函數(shù)中;

  2. await 右側(cè)的表達(dá)式一般為 promise 對(duì)象皂贩;

  3. await 返回的是 promise 成功的值栖榨;

  4. awaitpromise 失敗了, 就會(huì)拋出異常, 需要通過(guò) try...catch 捕獲處理。

 const p = new Promise((resolve, reject) => {
    // resolve('成功的值!');
    reject('失敗了!'); // 如果這里失敗 在async 中的await需要使用 try...catch() 捕獲
  });
  /**
   * await 需要放在 async 函數(shù)中
   */
  async function mainFun() {
    try {
      let result = await p;
      console.log(result);
    } catch (e) {
      console.log(e); // 失敗了! 是這里打印的哦
    }
  }
  // 調(diào)用函數(shù)
  mainFun();
async 和 await 讀取多個(gè)文件
  1. 需要node環(huán)境的支持明刷。

  2. 運(yùn)行時(shí)只需要在命令行 node 文件名.js 即可婴栽。

// 引入fs模塊
const fs = require("fs");

// 讀取文件
/**
 * 讀取文件 666.md
 */
function rf666() {
  return new Promise((resolve, reject) => {
    fs.readFile('../resources/666.md', (err, data) => {
      if (err) reject(err);
      resolve(data);
    });
  });
}


function rf888() {
  return new Promise((resolve, reject) => {
    fs.readFile('../resources/888.md', (err, data) => {
      if (err) reject(err);
      resolve(data);
    });
  });
}

function rf999() {
  return new Promise((resolve, reject) => {
    fs.readFile('../resources/999.md', (err, data) => {
      if (err) reject(err);
      resolve(data);
    });
  });
}

async function main() {
 try {
   let f666 = await rf666();
   let f888 = await rf888();
   let f999 = await rf999();
   console.log(f666.toString());
   console.log(f888.toString());
   console.log(f999.toString());
 } catch (e) {
   console.log(e);
 }
}
main();
async 和 await 封裝ajax請(qǐng)求
/**
   * 發(fā)送ajax請(qǐng)求返回的結(jié)果是一個(gè) Promise 對(duì)象
   */
  function sendAjax(url) {
    return new Promise((resolve, reject) => {
      // 1. 創(chuàng)建對(duì)象
      const xhr = new XMLHttpRequest();
      // 2. 初始化
      xhr.open('GET', url);
      // 3. 發(fā)送請(qǐng)求
      xhr.send();
      // 4. 綁定事件
      xhr.onreadystatechange = function () {
        // 判斷
        if (xhr.readyState === 4) { // 需要加上這句狀態(tài)的判斷否則請(qǐng)求不到數(shù)據(jù)
          // 判斷狀態(tài)碼 處于 200 - 299 之間
          if (xhr.status >= 200 && xhr.status <= 299) {
            // 表示成功
            // console.log(xhr.response);
            // 表示成功
            resolve(xhr.response);
          } else {
            // console.log(xhr.status);
            reject(xhr.status);
          }
        }
      };
    });
  }

  console.log(sendAjax('https://api.apiopen.top/getJoke'));
  /**
   * 使用then處理
   */
  sendAjax('https://api.apiopen.top/getJoke').then(value => {
    // console.log(value);
  }, reason => {
    console.log(reason);
  });

  // 使用 async 和 await 進(jìn)行處理
 async function main() {
   let joke = await sendAjax('https://api.apiopen.top/getJoke');
   console.log(joke);
 }
  main();

4.2 Object.values 和 Object.entries 、Object.keys()對(duì)象方法擴(kuò)展

  1. Object.values()方法返回一個(gè)給定對(duì)象的所有可枚舉屬性值的數(shù)組辈末;
  1. Object.entries()方法返回一個(gè)給定對(duì)象自身可遍歷屬性 [key,value]的數(shù)組愚争;
  1. Object.keys() 方法返回一個(gè)給定對(duì)象的所有可枚舉的屬性。

4.3 Object.getOwnPropertyDescriptors

該方法返回指定對(duì)象所有自身屬性的描述對(duì)象


5. ECMASript 9 新特性

5.1 Rest/Spread 屬性

  1. Rest 參數(shù)與 spread 擴(kuò)展運(yùn)算符在 ES6 中已經(jīng)引入挤聘,不過(guò) ES6 中只針對(duì)于數(shù)組轰枝,
    ES9 中為對(duì)象提供了像數(shù)組一樣的 rest 參數(shù)和擴(kuò)展運(yùn)算符
/**
   * 對(duì)象的擴(kuò)展運(yùn)算符
   */
  const connectCfg = {
    host: '127.0.0.1',
    port: '3306',
    username: 'root',
    password: 'root',
    type: 'db'
  }

  /**
   * 對(duì)象的展開(kāi)
   * @param host
   * @param port
   * @param user
   */
  function connect({host, port, ...user}) {
    console.log(host);
    console.log(port);
    console.log(user);
  }

  connect(connectCfg);

  const skillOne = {
    q: '天音波'
  };

  const skillTwo = {
    w: '金鐘罩'
  };

  const skillThree = {
    e: '天雷破'
  };

  const skillFour = {
    r: '猛龍擺尾'
  };

  // 將對(duì)象拆分為 數(shù)組
  const ms = {...skillOne, ...skillTwo, ...skillThree, ...skillFour};
  console.log(ms);

5.2 正則擴(kuò)展-命名捕獲分組

  1. ES9 允許命名捕獲組使用符號(hào)『?<name>』 ,這樣獲取捕獲結(jié)果可讀性更強(qiáng)
// 聲明一個(gè)字符串
  let str = '<a 

  // 編寫(xiě)正則
  let reg = /<a href="(?<url>.*)">(?<text>.*)<\/a>/;
  const result = reg.exec(str);
  console.log(result);
  console.log(result.groups.url);
  console.log(result.groups.text);

5.3 正則擴(kuò)展-反向斷言

  1. ES9 支持反向斷言组去,通過(guò)對(duì)匹配結(jié)果前面的內(nèi)容進(jìn)行判斷鞍陨,對(duì)匹配進(jìn)行篩選。
 /**
   * 1. 正向斷言
   *
   * 2. 反向斷言
   *
   */
    // 正向斷言
  let str = 'zhangsan1235656哈哈哈哈'
  const reg = /\d+(?=哈)/;
  const result = reg.exec(str);
  console.log(result);

  // 反向斷言 : 可以根據(jù)前邊的內(nèi)容做判斷
  const rg = /(?<=n)\d+/;
  console.log(rg.exec(str));

5.4 正則擴(kuò)展dot-All

  1. 正則表達(dá)式中點(diǎn).匹配除回車(chē)外的任何單字符从隆,標(biāo)記『s』 改變這種行為湾戳,允許行終止符出現(xiàn)。
let str =
    '<ul>
      <li>
        <a>肖申克的救贖</a>
        <p>上映時(shí)間:2019</p>
      </li>
      <li>
        <a>阿甘正傳</a>
        <p>上映時(shí)間:2018</p>
      </li>
    </ul>';
  /**
   * dot . 元字符 除換行符以外的任意單個(gè)字符
   *
   * 多了一個(gè)模式修正符 s
   *
   * g 全局修飾符
   */

  let reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs;
  let result;
  let data = [];
  while (result = reg.exec(str)) {
    data.push({title: result[1], time: result[2]});
  }
  console.log(data);

6. ES10 新特性

6.1 Object.fromEntries 和 Object.entries

  1. Object.fromEntries 將數(shù)組轉(zhuǎn)換為對(duì)象广料。
  1. Object.entries 將對(duì)象轉(zhuǎn)換為數(shù)組砾脑。
// 二維數(shù)組
  const result = Object.fromEntries([
      ['name', '仙桃大數(shù)據(jù)學(xué)院'],
      ['subject', 'Java、前端']
    ]);

  let map = new Map();
  map = Object.fromEntries(result);
  console.log(map);

6.1 trimEnd() 和 trimStart()

  1. trimEnd() 清除尾部的空白艾杏。
  1. trimStart() 清除首部的空白韧衣。

6.2 flat 和 flatMap

  1. flat 將多維數(shù)組轉(zhuǎn)換為低維數(shù)組 ,參數(shù)傳遞的是代表 深度购桑。
  1. flatMap 類(lèi)似于數(shù)組的 map 方法畅铭。map()方法創(chuàng)建一個(gè)新數(shù)組,其結(jié)果是該數(shù)組中的每個(gè)元素是調(diào)用一次提供的函數(shù)后的返回值勃蜘。參考網(wǎng)址

7. ES11 新特性 未完待續(xù)....

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末硕噩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子缭贡,更是在濱河造成了極大的恐慌炉擅,老刑警劉巖辉懒,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異谍失,居然都是意外死亡眶俩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)快鱼,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)颠印,“玉大人,你說(shuō)我怎么就攤上這事抹竹∠吆保” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵窃判,是天一觀的道長(zhǎng)闻坚。 經(jīng)常有香客問(wèn)我,道長(zhǎng)兢孝,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任仅偎,我火速辦了婚禮跨蟹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘橘沥。我一直安慰自己窗轩,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布座咆。 她就那樣靜靜地躺著痢艺,像睡著了一般。 火紅的嫁衣襯著肌膚如雪介陶。 梳的紋絲不亂的頭發(fā)上堤舒,一...
    開(kāi)封第一講書(shū)人閱讀 49,856評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音哺呜,去河邊找鬼舌缤。 笑死,一個(gè)胖子當(dāng)著我的面吹牛某残,可吹牛的內(nèi)容都是我干的国撵。 我是一名探鬼主播,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼玻墅,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼介牙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起澳厢,我...
    開(kāi)封第一講書(shū)人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤环础,失蹤者是張志新(化名)和其女友劉穎囚似,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體喳整,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谆构,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了框都。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片搬素。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖魏保,靈堂內(nèi)的尸體忽然破棺而出熬尺,到底是詐尸還是另有隱情,我是刑警寧澤谓罗,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布粱哼,位于F島的核電站,受9級(jí)特大地震影響檩咱,放射性物質(zhì)發(fā)生泄漏揭措。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一刻蚯、第九天 我趴在偏房一處隱蔽的房頂上張望绊含。 院中可真熱鬧,春花似錦炊汹、人聲如沸躬充。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)充甚。三九已至,卻和暖如春霸褒,著一層夾襖步出監(jiān)牢的瞬間伴找,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工废菱, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疆瑰,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓昙啄,卻偏偏與公主長(zhǎng)得像穆役,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子梳凛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容