撩課-Web架構師養成系列(第一篇)-ES6/7/8

前言html

Web架構師養成系列共15篇,每週更新一篇,主要分享、探討目前大前端領域(前端、後端、移動端)企業中正在用的各類成熟的、新的技術。前端

部分文章也會分析一些框架的底層實現,讓咱們作到知其然知其因此然。es6

探討、交流、資料獲取請加我微信yejh9522ajax

本篇文章閱讀須要時長:約15分鐘後端

1、ECMAScript 6/7/8簡介數組

ECMAScript 6.0,簡稱ES6,第一個版本是在2015年6月進行發佈,因此也稱之爲《ECMAScript 2015 標準》(簡稱 ES2015)。瀏覽器

JavaScript是ECMAScript的一種實現(分支),遵循ECMAScript標準的。目前主流瀏覽器已經能夠完美兼容和使用ES6。ES7/8部分新特性也已經被用於咱們的實際開發中。bash

image

本篇主要講解ES6的知識點,內容以下:let和const、解構賦值、字符串操做、函數、數組API、集合、對象拷貝、延展操做符、對象補充、Generator、Proxy、Reflect。微信

2、let和const網絡

ES6新增了let和const來聲明變量,主要是解決var聲明變量所形成的困擾和問題:

var不能用於定義常量
  
  var能夠重複聲明變量
  
  var存在變量提高
  
  var不支持塊級做用域
複製代碼

而let和const解決了以上問題,具體操做以下:

1)不能夠重複聲明變量

let site = 'itLike';
let site = 'itLike';
console.log(site);
複製代碼

運行結果:

Identifier 'site' has already been declared
複製代碼

2)不存在變量提高

console.log(site);
複製代碼
let site = 'itLike';
運行結果:
 site is not defined
複製代碼

3)能夠定義常量

不能給常量從新賦值,但若是是引用類型的話能夠進行修改。

// 天然對數的底
const E = 2.718;
E = 2.71;
console.log(E);
運行結果:
Assignment to constant variable.

//引用類型
const LK = {
 name:'itLike',
 intro: '喜歡IT, 就上撩課(itLike.com)'
};

LK.name = '撩課';
console.log(LK);

運行結果:
複製代碼

image

4) 塊級做用域

若是用var定義變量,變量是經過函數或者閉包擁有做用域;但,如今用let定義變量,不只僅能夠經過函數/閉包隔離,還能夠經過塊級做用域隔離。

塊級做用域用一組大括號定義一個塊,使用 let 定義的變量在大括號的外部是訪問不到的,此外,let聲明的變量不會污染全局做用域。

{let site = 'itLike';}
console.log(site);
複製代碼

運行結果:

site is not defined
if(1){let str = '小撩';}
console.log(str);

運行結果:
str is not defined
複製代碼

5)案例運用

高級排他實現(再也不使用閉包)

image

3、解構賦值

用於分解js中對象的結構。

1) 用於數組的結構

// 普通寫法
let nameArr = ['撩課', '小撩', '小煤球'];
let name1 = nameArr[0];
let name2 = nameArr[1];
let name3 = nameArr[2];

// 解構寫法
let [name1, name2, name3] = nameArr;
console.log(name1, name2, name3);
複製代碼

2)對象的解構

// 寫法1
let {name, age, sex}= {name: '小煤球', age: 1, sex: '公'};
// 結果: 小煤球 1 公
console.log(name, age, sex);

// 寫法2: 解構重命名
let {name: lkName, age: lkAge, sex: lkSex}
= {name: '小煤球', age: 1, sex: '公'};
// 結果: 小煤球 1 公
console.log(lkName, lkAge, lkSex);

// 寫法3:能夠設置默認值
let {name, age, sex = '公'}
= {name: '小煤球', age: 1};
console.log(sex);  // 公

// 寫法4:省略解構
let [, , sex] = ['小煤球', 1, '公 '];
console.log(sex);
複製代碼

3) 應用場景

在封裝ajax的GET和POST請求時, 就能夠運用到解構的知識點,代碼以下:

image

4、延展操做符

1)延展數組

let arr1 = [ 'a', 'b', 'c'];
  let arr2 = [1, 2, 3];
  let result = [...arr1, ...arr2];
  console.log(result);
  // [ "a", "b", "c", 1, 2, 3 ]
複製代碼

2)延展對象

let smallDog = {name:'小煤球', age: 1};
  let bigDog = {name: 'Python', age: 2};
  let dog = {...smallDog, ...bigDog};
  console.log(dog);
  // {name: "Python", age: 2}
複製代碼

注意: 若是對象中的屬性一致, 會被覆蓋

3)開發應用場景

function getMinValue() {
    console.log(Math.min(...arguments));
  }
  
  getMinValue(1, -99, 22, 10, 9); // -99
複製代碼

5、字符串操做 新增字符串方法

1) startsWith()

判斷字符串是否以 XX 開頭
let url = 'http://www.itlike.com';
console.log(url.startsWith('http')); // true
複製代碼

2) endsWith()

判斷字符串是否以 XX 結尾
let file = 'index.html';
console.log(file.endsWith('html')); // true
複製代碼

3) includes()

判斷字符串中是否包含 XX
let str = 'liaoke';
console.log(str.includes('ao')); // true
複製代碼

4) repeat()

拷貝n份
let title = '撩課在線';
console.log(title.repeat(100));
複製代碼

5) padStart() / padEnd()

padStart()用於頭部補全,
padEnd()用於尾部補全;
第一個參數用來指定字符串的最小長度,
第二個參數是用來補全的字符串。

// "2030111111"
let y1 = '2030'.padEnd(10, '1');

// "2030-11-22"
let y2 = '11-22'.padStart(10, '2030-MM-DD');

console.log(y1, y2);
複製代碼

模板字符串

1) 模板字符串

模板字符串用反引號(`)包含,變量用${}括起來; 在開發中使用是很是靈活的。

let name = '小煤球';
 let sex = '公';
 let result = `我叫 ${name} , 我是 ${sex} 的`;
console.log(result);
// 我叫 小煤球 , 我是 公 的
複製代碼

2) 模板字符串遍歷插入

image

3) 模板字符串實現原理

let name = '小煤球';
let sex = '公';
let result = `我叫 ${name} , 我是 ${sex} 的`;
result = result.replace(/\${([^}]*)}/g);
console.log(result);
複製代碼

6、函數操做

1) 設置默認參數

function logPerson(name, sex = '男', age = 20) {
console.log(name);
console.log(sex);
console.log(age);
}

// undefined 男 20

logPerson();
複製代碼

2)延展參數轉化

let logName = function (arg1, ...arg2) {
 console.log(arg1, arg2);
};
// 宋小寶 , ["趙薇", "王菲", "那英"]
logName('宋小寶', '趙薇', '王菲', '那英');
複製代碼

3)箭頭函數

箭頭函數簡化了函數的的定義方式; 通常以 "=>" 操做符左邊爲輸入的參數; 而右邊則是進行的操做以及返回的值 inputs => output。

["趙薇", "王菲", "那英"].forEach(
 val => console.log(val)
 );
複製代碼

注意:

1)多個參數要用()包起來,函數體有多條語句須要用{}包起來; 2)箭頭函數根本沒有本身的this,因此內部的this就是外層代碼塊的this。 正是由於它沒有this,從而避免了this指向的問題; 3)箭頭函數中沒有arguments對象。

image

注意:

1)let聲明的變量不會放在window上 2)對象不是做用域

let site = 'like.com';
 let obj = {
    site: '撩課',
    func: () => {
      // this指向window
      console.log(this);
      // undefined
      console.log(this.site);
     }
 };

let func = obj.func;
func();
複製代碼

7、數組新增方法

ES6中在原有數組的方法上又新增了一些好用的方法,好比:forEach、findIndex、find、map、reduce、filter、every、some等。

1)Array.from()

將一個數組或者類數組變成新數組,是淺拷貝操做。

let oldArr = ['小煤球', 10, {df1: '小Python', df2: '土豆'}];
let newArr = Array.from(oldArr);
console.log(newArr === oldArr); // false
複製代碼

2)Array.of()

建立一個具備可變數量參數的新數組實例,而不考慮參數的數量或類型。

// [8]
  console.log(Array.of(8));
  // [1, 2, 3]
  console.log(Array.of(1, 2, 3));
  // [ , , , , , , ]
  console.log(Array(8));
  // [1, 2, 3]
  console.log(Array(1, 2, 3));
複製代碼

3)Array.fill()

用一個固定值填充一個數組中從起始索引到終止索引內的所有元素。 語法結構:arr.fill(value[, start[, end]])

let array1 = [1, 2, 3, 4, 5];
  // 用 撩 替換 索引[2,5]中的內容
  console.log(array1.fill('撩', 2, 5));
  // 用 撩 替換 索引[1]中的內容
  console.log(array1.fill('撩', 1));
  // 用 撩 替換 數組中全部內容
  console.log(array1.fill('撩'));
複製代碼

運行結果:

image

8、對象操做 8.1 屬性簡寫

若是對象中屬性值和變量名同樣,而且屬性的值就是變量表示值,則簡寫。

image

8.2 super

經過super能夠調用prototype上的屬性或方法。

image

** 8.3 Object.is **

對比兩個值是否相等

> console.log(Object.is(Array, Object));
複製代碼

8.4 Object.setPrototypeOf

將一個指定的對象的原型設置爲另外一個對象或者null

let dog1 = { name: '小煤球' };
  let obj = {name: 'xxx'};
  Object.setPrototypeOf(dog1, obj);
  let dog2 = {
     __proto__: obj
  };
  console.log(dog1.__proto__.name);
  console.log(dog2.__proto__.name);
複製代碼

8.5 對象拷貝-深拷貝和淺拷貝

1)淺拷貝

Object.assign拷貝
  
  let obj1 = { dog1: { name: '小煤球' } };
  let obj2 = { name: '小Python' };
  let obj = {};
  Object.assign(obj, obj1, obj2);
  console.log(obj);

  延展拷貝
  
  let obj1 = { dog1: { name: '小煤球' } };
  let obj2 = { name: '小Python' };
  console.log({ ...obj1, ...obj2 });
複製代碼

2)深拷貝

JSON.parse和JSON.stringify
 
  let obj1 = { dog1: { name: '小煤球' } };
  let obj2 = { name: '小Python' };
  console.log(JSON.parse(JSON.stringify({ ...obj1, ...obj2 })));
複製代碼

遞歸調用實現

image

9、類操做

在以前定義類是經過構造函數來操做的,es6新增了class關鍵字,此時,咱們也能夠像其它語言同樣來建立各類類了。

class Person{
  constructor(name, age){
      this.name = name;
      this.age = age;
  }
 
  print(){
    console.log('我叫' + this.name + ',今年' + this.age + '歲');
  }
}
複製代碼

類的繼承

小案例:五彩小球

運行效果:

image

核心代碼:

image
image

10、集合操做

1.set

一個Set是一堆東西的集合,Set有點像數組,不過跟數組不同的是,Set裏面不能有重複的內容;

// 建立一個集合
let set = new Set(['張三', '李四', '王五', '張三', '李四']);
console.log(set);
  
// 一個屬性
console.log(set.size);
  
// 四個方法
// add
console.log(set.add('劉德華').add('旋之華'));
console.log(set);
  
// delete
console.log(set.delete('張三'));
console.log(set.delete('李四'));
console.log(set);
  
// has
console.log(set.has('張三'));
console.log(set.has('張三1'));
  
// clear
console.log(set.clear()); // undefined
console.log(set);
複製代碼

2)map

Map結構提供了「值—值」的對應,是一種更完善的Hash結構實現。

若是你須要「鍵值對」的數據結構,Map比Object更合適。

它相似於對象,也是鍵值對的集合,可是「鍵」的範圍不限於字符串,各類類型的值(包括對象)均可以看成鍵。

實例屬性和方法:size、set、get、has、delete、clear

// 建立一個Map
  let obj1 = {a: 1}, obj2 = {b: 2};
  const map = new Map([
     ['name', '張三'],
     ['age', 18],
     ['sex', '男'],
     [obj1, '今每天氣很好'],
     [obj2, '適合敲代碼'],
     [[1,2], 'hhh']
  ]);
  
  console.log(map);
  console.log(map.size);
  // set和get
  map.set('friends', ['趙六', '力氣']).set(['dog'], '小花');
  console.log(map);
  console.log(map.get('name'));
  console.log(map.get(obj1));
  
  // delete
  map.delete(obj1);
  console.log(map.delete('xxxx'));
  console.log(map);
  
  // has
  console.log(map.has(obj1));
  console.log(map.has(obj2));
  
  // clear
  map.clear();
  console.log(map);
  
  // 遍歷
  map.forEach(function (value, index) {
     console.log(index + ':' + value);
  });
  
  // 注意事項
  map.set({}, '呵呵呵呵呵');
  map.set({}, '哈哈哈哈');
  
  console.log(map);
  console.log({} === {});
複製代碼

11、Generator

爲何要使用generator?

開發中, 好比在作網絡請求時咱們會進行異步調用,爲了保證調用順序的正確性,一般咱們會用回調函數,也能夠採用Promise相關的技術來操做。

還有一種經常使用的解決方案,它就是Generator生成器函數。

顧名思義,它是一個生成器,它也是一個狀態機,內部擁有值及相關的狀態,生成器返回一個迭代器Iterator對象,咱們能夠經過這個迭代器,手動地遍歷相關的值、狀態,保證正確的執行順序。

1)聲明

Generator的聲明方式相似通常的函數聲明,只是多了個*號,而且通常能夠在函數內看到yield關鍵字。

function* showNames() {
      yield '張三';
      yield '李四';
      return '王五';
  }
  
  let show = showNames();
   // {done: false, value: "張三"}
  
  console.log(show.next());
  // {done: false, value: "李四"}
  
  console.log(show.next()); 
  // {done: true, value: "王五"}
  
  console.log(show.next()); 
  // {done: true, value: undefined}
  
  console.log(show.next());
複製代碼

迭代器有一個next方法,每次執行的時候會返回一個對象,對象裏面有兩個屬性,一個是value表示返回的值,還有就是布爾值done,表示是否迭代完成。

2)模擬實現

image

12、Proxy&&Reflect (瞭解)

從語法角度講JavaScript不支持重載。

緣由很簡單,JS中函數能夠傳入任意類型、任意個數的參數, 統統能夠經過在函數內使用this.arguments得到。

這樣,就沒法實現同名函數參數列表不一樣實現不一樣功能。

固然,在實際使用過程當中,能夠人爲去檢測傳入實參的個數及類型,來進行不一樣操做。 可是,這不能叫作重載。

ES6帶來了Proxy和Reflect,配合使用能夠實現重載。

Proxy用於修改某些操做的默認行爲,至關於對原始想進行的操做進行「包裝」;

Reflect對象的方法與Proxy對象的方法一一對應,這使得Proxy對象能夠方便的調用對應的Reflect方法完成默認行爲。

set實現:

image

PS: 什麼時重載?

簡單說,就是函數或者方法有相同的名稱,可是參數列表不相同的情形,這樣的同名不一樣參數的函數或者方法之間,互相稱之爲重載函數或者方法。

獲取代碼,有疑惑、答疑,加我微信yejh9522溝通交流便可;下篇更新預告: ES7/8新特性,Async和Promise

相關文章
相關標籤/搜索