收錄 項目開發當中經常使用ES六、七、8的 知識點javascript
ES6推薦的編碼風格:es6.ruanyifeng.com/#docs/style值得注意java
ECMAScript 和 JavaScript 的關係是,前者是後者的規格,後者是前者的一種實現es6
2015年6月正式經過成爲國際標準。ajax
Babel 是一個普遍使用的 ES6 轉碼器,能夠將 ES6 代碼轉爲 ES5 代碼,從而在現有環境執行。編程
var的時代主要有三大痛點:json
ES6 const和let的出現就是爲了解決以上三個痛點。數組
聲明後不可再次修改,不然會報錯。promise
支持塊級做用域瀏覽器
// 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。
複製代碼
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.trunc
方法用於去除一個數的小數部分,返回整數部分。
Math.trunc(4.1) // 4
Math.trunc(-4.1) // -4
Math.trunc(-0.1234) // -0
複製代碼
形式爲...變量名
),用於獲取函數的多餘參數,這樣就不須要使用arguments
對象了。rest 參數搭配的變量是一個數組,該變量將多餘的參數放入數組中。
function push(array, ...items) {
複製代碼
主要修復this指向的問題。 函數體內的this對象 就是定義時所在的對象,而不是以前使用時所在的對象。
function(參數){ }
(參數)=>{ return xxx }
若是,有且僅有1個參數,()也能夠省
若是,有且僅有1條語句-return,{}能夠省
複製代碼
aItems.filter(item=>item.loc==cur_loc) //單個條件
.filter(item=>item.price>=60 && item.price<100);//多個條件
求和、求平均數...
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']
複製代碼
[1, 4, -5, 10].find((n) => n < 0)
// -5
複製代碼
Array.prototype.includes
方法返回一個布爾值,表示某個數組是否包含給定的值,與字符串的includes
方法相似
[1, 2, 3].includes(2) // true
[1, 2, 3].includes(4) // false
[1, 2, NaN].includes(NaN) // true
複製代碼
Object.is('foo', 'foo')
// true
Object.is({}, {})
// false
複製代碼
Object.assign
方法用於對象的合併,將源對象(source)的全部可枚舉屬性,複製到目標對象(target)。
let ab = { ...a, ...b };
// 等同於
let ab = Object.assign({}, a, b);
複製代碼
ES5 的Object.getOwnPropertyDescriptor()
方法會返回某個對象屬性的描述對象(descriptor)。ES2017 引入了Object.getOwnPropertyDescriptors()
方法,返回指定對象全部自身屬性(非繼承屬性)的描述對象。
是異步編程的一種解決方案,比傳統的 -- 回調函數和事件 更合理和更強大。
兩大特色:
pending
(進行中)、fulfilled
(已成功)和rejected
(已失敗),只有異步操做的結果,能夠決定當前是哪種狀態,任何其餘操做都沒法改變這個狀態。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
方法是.then(null, rejection)
或.then(undefined, rejection)
的別名,用於指定發生錯誤時的回調函數。
getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 處理 getJSON 和 前一個回調函數運行時發生的錯誤
console.log('發生錯誤!', error);
});
複製代碼
Promise.all()
方法用於將多個 Promise 實例,包裝成一個新的 Promise 實例。
const p = Promise.all([p1, p2, p3]);
複製代碼
p
的狀態由p1
、p2
、p3
決定,分紅兩種狀況。 (1)只有p1
、p2
、p3
的狀態都變成fulfilled
,p
的狀態纔會變成fulfilled
,此時p1
、p2
、p3
的返回值組成一個數組,傳遞給p
的回調函數。 (2)只要p1
、p2
、p3
之中有一個被rejected
,p
的狀態就變成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('錯了');
});
複製代碼
ES2017標準引入async函數,使得異步操做變得更加方便。它是 Generator函數的語法糖。
進一步說,async
函數徹底能夠看做多個異步操做,包裝成的一個 Promise 對象,而await
命令就是內部then
命令的語法糖。
生成實例對象的傳統方法是經過 構造函數,
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
對象。
在ES6以前 社區主要有 CommonJS 和 AMD 兩種。前者用於服務器,後者用於瀏覽器。 ES6的誕生徹底取代了二者,成爲 瀏覽器和服務器通用的模塊解決方案。
特色: es6模塊的設計思想是 儘可能的靜態化,使得編譯時就能肯定模塊的依賴關係,以及輸入和輸出的變量。CommonJS和AMD 都只能在運行時肯定這些東西。
基礎 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'
複製代碼
默認方式:
<!-- 外部腳本 -->
<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>
複製代碼