ES6【掌握篇】

收錄 項目開發當中經常使用ES六、七、8的 知識點javascript

ES6推薦的編碼風格:es6.ruanyifeng.com/#docs/style值得注意java

簡介

ECMAScript

ECMAScript 和 JavaScript 的關係是,前者是後者的規格,後者是前者的一種實現es6

ES2015 (ES6)

2015年6月正式經過成爲國際標準。ajax

Babel轉碼器

Babel 是一個普遍使用的 ES6 轉碼器,能夠將 ES6 代碼轉爲 ES5 代碼,從而在現有環境執行。編程

變量

var的時代主要有三大痛點json

  1. 可重複聲明
  2. 沒有塊級做用域
  3. 不可限制(常量、變量)

ES6 const和let的出現就是爲了解決以上三個痛點。數組

const:聲明常量

聲明後不可再次修改,不然會報錯。promise

let:聲明變量

支持塊級做用域瀏覽器

變量提高問題

// var 的狀況
console.log(foo); // 輸出undefined
var foo = 2;

// let 的狀況
console.log(bar); // 報錯ReferenceError
let bar = 2;
複製代碼

塊級做用域{}

同一塊級做用域{}下不可重複聲明bash

塊級做用域的出現,使得得到普遍應用的匿名當即執行函數表達式(匿名 IIFE)再也不必要了。

反例:
window.onload=function (){
  var aBtn = document.getElementsByTagName('input');

  for(var i=0;i < aBtn.length;i++){
    aBtn[i].onclick=function (){
      alert(i); //猜測彈出的i是多少?
    };
  }
};
複製代碼

解構賦值

對象的解構與數組有一個重要的不一樣。 數組的元素是按次序排列的,變量的取值由它的位置決定;而對象的屬性沒有次序,變量必須與屬性同名,才能取到正確的值。

// 左邊和右邊 必須對應起來
對象:
let {a, b, c } = {a:123, b:12313, c:35234234}  // 對象解構賦值
let { baz } = { foo: 'aaa', bar: 'bbb' };
baz // undefined



數組:
let [a, b, c] = [12, 5, 8];   // 數組解構賦值
let [head, ...tail] = [1, 2, 3, 4];
head // 1
tail // [2, 3, 4]

let [bar, foo] = [1];
以上狀況都屬於解構不成功,foo的值都會等於undefined複製代碼

字符串的新增方法

includes(), startsWith(), endsWith()

  • includes():返回布爾值,表示是否找到了參數字符串。
  • startsWith():返回布爾值,表示參數字符串是否在原字符串的頭部。
  • endsWith():返回布爾值,表示參數字符串是否在原字符串的尾部。
let url='http://www.bing.com/a';
url.startsWith('http://') || url.startsWith('https://')

url.startsWith('http') // true
url.endsWith('a') // true
url.includes('o') // true
複製代碼

Math 對象的擴展

Math.trunc()

Math.trunc方法用於去除一個數的小數部分,返回整數部分。

Math.trunc(4.1) // 4
Math.trunc(-4.1) // -4
Math.trunc(-0.1234) // -0
複製代碼

函數的擴展

rest 參數

形式爲...變量名),用於獲取函數的多餘參數,這樣就不須要使用arguments對象了。rest 參數搭配的變量是一個數組,該變量將多餘的參數放入數組中。

function push(array, ...items) {
複製代碼

箭頭函數

精髓

主要修復this指向的問題。 函數體內的this對象 就是定義時所在的對象,而不是以前使用時所在的對象。

簡潔

function(參數){   }
(參數)=>{ return xxx  }

若是,有且僅有1個參數,()也能夠省
若是,有且僅有1條語句-return,{}能夠省
複製代碼

數組的擴展

  • map       映射    1對1
  • forEach   遍歷    循環一遍
  • filter    過濾

aItems.filter(item=>item.loc==cur_loc) //單個條件

.filter(item=>item.price>=60 && item.price<100);//多個條件

  • reduce    減小    多對1

求和、求平均數...

Array.from()

Array.from方法用於將兩類對象轉爲真正的數組:相似數組的對象(array-like object)和可遍歷(iterable)的對象(包括 ES6 新增的數據結構 Set 和 Map)。

let arrayLike = {
    '0': 'a',
    '1': 'b',
    '2': 'c',
    length: 3
};
// ES5的寫法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的寫法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']
複製代碼

數組實例的 find() 和 findIndex()

  • find():用於找出第一個符合條件的數組成員
[1, 4, -5, 10].find((n) => n < 0)
// -5
複製代碼
  • findIndex():返回第一個符合條件的數組成員的位置,若是全部成員都不符合條件,則返回-1

數組實例的 includes()

Array.prototype.includes方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的includes方法相似

[1, 2, 3].includes(2)     // true
[1, 2, 3].includes(4)     // false
[1, 2, NaN].includes(NaN) // true
複製代碼

對象的擴展

屬性的遍歷

  1. for...in: 循環遍歷對象自身的和繼承的可枚舉屬性(不含 Symbol 屬性)。
  2. Object.keys(obj):返回數組,包括對象自身的(不含繼承的)全部可枚舉屬性的鍵名
  3. Object.getOwnPropertyNames(obj):返回數組,包含對象自身的全部屬性的鍵名(不含symbol屬性,但包含不可枚舉屬性

比較兩個值是否真相等Object.is()

Object.is('foo', 'foo')
// true
Object.is({}, {})
// false
複製代碼

Object.assign淺拷貝

Object.assign方法用於對象的合併,將源對象(source)的全部可枚舉屬性,複製到目標對象(target)。

let ab = { ...a, ...b };
// 等同於
let ab = Object.assign({}, a, b);
複製代碼

Object.getOwnPropertyDescriptors()

ES5 的Object.getOwnPropertyDescriptor()方法會返回某個對象屬性的描述對象(descriptor)。ES2017 引入了Object.getOwnPropertyDescriptors()方法,返回指定對象全部自身屬性(非繼承屬性)的描述對象。

Promise 對象

是異步編程的一種解決方案,比傳統的 -- 回調函數和事件  更合理和更強大。

原理介紹

兩大特色:

  1. 對象不受外界影響(承諾):有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗),只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。
  2. Promise對象的狀態改變,只有兩種可能:從pending變爲fulfilled和從pending變爲rejected

有了Promise對象,就能夠將異步操做以同步操做的流程表達出來,避免了層層嵌套的回調函數。此外,Promise對象提供統一的接口,使得控制異步操做更加容易。

基本用法

建立一個Promise實例

const promise = new Promise(function(resolve, reject) {
  // ... some code

  if (/* 異步操做成功 */){
    resolve(value);
  } else {
    reject(error);
  }
});
複製代碼

Promise實例生成之後,能夠用then方法分別指定resolved狀態和rejected狀態的回調函數。

promise.then(function(value) {
  // success 狀態變爲resolved時調用
}, function(error) {
  // failure 狀態變爲rejected時調用
});
複製代碼

Promise.prototype.catch()

Promise.prototype.catch方法是.then(null, rejection).then(undefined, rejection)的別名,用於指定發生錯誤時的回調函數。

getJSON('/posts.json').then(function(posts) {
  // ...
}).catch(function(error) {
  // 處理 getJSON 和 前一個回調函數運行時發生的錯誤
  console.log('發生錯誤!', error);
});
複製代碼

Promise.all()

Promise.all()方法用於將多個 Promise 實例,包裝成一個新的 Promise 實例。

const p = Promise.all([p1, p2, p3]);
複製代碼

p的狀態由p1p2p3決定,分紅兩種狀況。 (1)只有p1p2p3的狀態都變成fulfilledp的狀態纔會變成fulfilled,此時p1p2p3的返回值組成一個數組,傳遞給p的回調函數。 (2)只要p1p2p3之中有一個被rejectedp的狀態就變成rejected,此時第一個被reject的實例的返回值,會傳遞給p的回調函數。

Promise.all([
  $.ajax({url: 'data/1.json', dataType: 'json'}),
  $.ajax({url: 'data/2.json', dataType: 'json'}),
  $.ajax({url: 'data/3.json', dataType: 'json'}),
]).then((arr)=>{
  let [data1, data2, data3]=arr;

  console.log(data1, data2, data3);
}, (res)=>{
  alert('錯了');
});
複製代碼

async\await

ES2017標準引入async函數,使得異步操做變得更加方便。它是 Generator函數的語法糖。

  1. 內置執行器:與普通函數同樣直接調用
  2. 更好的語義:async 表示函數裏有異步操做、await 表示緊跟在後面的表達式須要同步(等待結果)。
  3. 更廣的適用性:能夠是Promise對象 和 原始類型的值(會自動轉成當即resolved的Promise對象)
  4. 返回值 是 Promise:這樣就能夠直接適用 then來執行下一步操做了。

進一步說,async函數徹底能夠看做多個異步操做,包裝成的一個 Promise 對象,而await命令就是內部then命令的語法糖。

class

基本用法

生成實例對象的傳統方法是經過 構造函數,

function Point (x, y) {
	this.x = x;
  this.y = y
}
Point.prototype.toString = function () {
	return this.x + this.y
}

var p = new Point(1, 2)// 3
複製代碼

ES6引入Class的概念,讓 對象原型的寫法更加清晰、更像面向對象編程的語法(就是一個語法糖)

class Point () {
  constructor(x, y) {   // 構造函數 一個類必須有constructor方法
    this.x = x;
    this.y = y;
  }
  toString() {
  	return this.x + this.y;
  }
}
var p = new Point();
p.toString() // 
複製代碼

繼承

Class 能夠經過extends關鍵字實現繼承,這比 ES5 的經過修改原型鏈實現繼承,要清晰和方便不少。

class ColorPoint extends Point {
  constructor(x, y, color) {
    super(x, y); // 調用父類的constructor(x, y)
    this.color = color;
  }

  toString() {
    return this.color + ' ' + super.toString(); // 調用父類的toString()
  }
}
複製代碼

super: 既能夠 看成函數使用,也能夠看成對象使用。 子類必須在constructor方法中調用super方法,不然新建實例時會報錯。 super它在這裏表示父類的構造函數,用來新建父類的this對象。

Module 模塊體系

語法

在ES6以前 社區主要有 CommonJS 和 AMD 兩種。前者用於服務器,後者用於瀏覽器。  ES6的誕生徹底取代了二者,成爲 瀏覽器和服務器通用的模塊解決方案。

特色: es6模塊的設計思想是 儘可能的靜態化,使得編譯時就能肯定模塊的依賴關係,以及輸入和輸出的變量。CommonJS和AMD 都只能在運行時肯定這些東西。

  • CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用。
  • CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口。

基礎 ES6 模塊不是對象,而是經過export命令顯式指定輸出的代碼,再經過import命令輸入

// profile.js
export var firstName = 'Michael';  //1. 普通方式

var year = 1958;  // 2. 使用{}指定索要輸出的一組變量 (推薦寫法)
export { year };

// export-default.js
export default function() {xxx}  //3. 默認輸出函數,其餘模塊加載該模塊時,import命令能夠爲該匿名函數指定任意名字。
// import-default.js
import customName from './export-default';
customName(); // 'foo'
複製代碼

js加載實現

默認方式:

<!-- 外部腳本 -->
<script type="application/javascript" src="path/to/myModule.js"></script>
//默認狀況下,瀏覽器是同步加載 JavaScript 腳本,即渲染引擎遇到<script>標籤就會停下來,等到執行完腳本,再繼續向下渲染。
複製代碼

ES6 方式:

<script src="path/to/myModule.js" defer></script>
<script src="path/to/myModule.js" async></script>
// <script>標籤打開defer或async屬性,腳本就會異步加載。
複製代碼

一句話,defer是「渲染完再執行」,async是「下載完就執行」。另外,若是有多個defer腳本,會按照它們在頁面出現的順序加載,而多個async腳本是不能保證加載順序的。

**ES6模塊: **瀏覽器加載 ES6 模塊,也使用<script>標籤,可是要加入type="module"屬性。、

<script type="module" src="./foo.js"></script>
複製代碼
相關文章
相關標籤/搜索