介紹
ECMAScript 6 在接下來的一段時間內(nèi)將成為 ECMAScript的一個標(biāo)準,。這個標(biāo)準預(yù)計在今年的時候就會被簽署,,不管在Github,還是在很多社區(qū),,javascript愛好者已經(jīng)早已開始擁抱變化,享受ES6 帶來的美好,這篇文章將介紹ES6的一些新特性,。由于ES6 還沒有很好地被瀏覽器支持,,所以這篇文章的ES6代碼將使用 Babel 進行編譯。
ECMAScript 6 的新特性
箭頭(Arrow)
=> 是function的簡寫形式,,支持expression 和 statement 兩種形式,。同時一點很重要的是它擁有詞法作用域的this值,幫你很好的解決this的指向問題,,這是一個很酷的方式,,可以幫你減少一些代碼的編寫,先來看看它的語法,。
([param] [, param]) => {
statements
}
param => expression
然后再來看看例子,,以及babel 編譯后的結(jié)果。
ES6:
babel編譯后結(jié)果:
類(class)
ES6 引入了class(類),,讓javascript的面向?qū)ο缶幊套兊酶尤菀浊逦腿菀桌斫?。類只是基于原型的面向?qū)ο竽J降恼Z法糖。
class Animal {
// 構(gòu)造方法,實例化的時候?qū)徽{(diào)用,,如果不指定,,那么會有一個不帶參數(shù)的默認構(gòu)造函數(shù).
constructor(name,color) {
this.name = name;
this.color = color;
}
// toString 是原型對象上的屬性
toString() {
console.log('name:' + this.name + ',color:' + this.color);
}
}
var animal = new Animal('dog','white');
animal.toString();
console.log(animal.hasOwnProperty('name')); //true
console.log(animal.hasOwnProperty('toString')); // false
console.log(animal.__proto__.hasOwnProperty('toString')); // true
class Cat extends Animal {
constructor(action) {
// 子類必須要在constructor中指定super 方法,否則在新建實例的時候會報錯.
// 如果沒有置頂consructor,默認帶super方法的constructor將會被添加,、
super('cat','white');
this.action = action;
}
toString() {
console.log(super.toString());
}
}
var cat = new Cat('catch')
cat.toString();
// 實例cat 是 Cat 和 Animal 的實例,,和Es5完全一致。
console.log(cat instanceof Cat); // true
console.log(cat instanceof Animal); // true
類的 prototype 屬性和 __proto__ 屬性
在上一篇 javascript面向?qū)ο缶幊?/a> 中我們已經(jīng)了解到一個實例化對象會有一個 __proto__ 指向構(gòu)造函數(shù)的 prototype 屬性,。在 class 中,。同時具有 __proto__ 和 prototype 兩個屬性,存在兩條繼承鏈,。
子類的 __proto__ 屬性,,表示構(gòu)造函數(shù)的繼承,總是指向父類,。
子類的 prototype 的 __proto__ 屬性表示方法的繼承,,總是指向父類的 prototype 屬性。
class Cat extends Animal {}
console.log(Cat.__proto__ === Animal); // true
console.log(Cat.prototype.__proto__ === Animal.prototype); // true
我們先來看第一條 Cat.__proto__ === Animal 這條原型鏈,。完成構(gòu)造函數(shù)繼承的實質(zhì)如下:
class Cat extends Animal {
construcotr() {
return Animal.__proto__.call(this);
}
}
第二條對原型鏈 Cat.prototype.__proto__ === Animal.prototype 完成方法的繼承,,實質(zhì)如下:
Cat.prototype.__proto__ = Animal.prototype
另外還有還有三種特殊情況。
class A extends Object {}
console.log(A.__proto__ === Object); // true
console.log(A.prototype.__proto__ === Object.prototype);
A繼承Object,,A的__prototype__ 指向父類Object. A的 prototype.__proto__ 指向父類Object的prototype,。
從上篇文章中的 函數(shù)對象的原型 中我們可以了解到,函數(shù)是一種特殊的對象,,所有函數(shù)都是 Function 的實例。
class Cat {}
console.log(Cat.__proto__ === Function.prototype); //true
console.log(Cat.prototype.__proto__ === Object.prototype); //true
由于Cat不存在任何繼承,,就相當(dāng)于一個普通函數(shù),,由于函數(shù)都是Function 的實例,所以 Cat.__proto__ 指向 Function.prototype. 第二條繼承鏈指向父類(Function.prototype) 的prototype屬性,,所以 Cat.prototype.__proto__ === Object.prototype . Cat調(diào)用后會返回Object實例,,所以 A.prototype.__proto__ 指向構(gòu)造函數(shù)(Object)的prototype。
class Cat extends null {};
console.log(Cat.__proto__ === Function.prototype); // true;
console.log(Cat.prototype.__proto__ === null); //true
Cat是一個普通函數(shù),,所以繼承 Function.prototype .第二條繼承鏈不繼承任何方法,,所以 Cat.prototype.__proto__ == null .
Module
到目前為止,javascript (ES5及以前) 還不能支持原生的模塊化,大多數(shù)的解決方案都是通過引用外部的庫來實現(xiàn)模塊化,。比如 遵循CMD規(guī)范的 Seajs 和AMD的 RequireJS ,。在ES6中,模塊將作為重要的組成部分被添加進來,。模塊的功能主要由 export 和 import 組成.每一個模塊都有自己單獨的作用域,,模塊之間的相互調(diào)用關(guān)系是通過 export 來規(guī)定模塊對外暴露的接口,通過import 來引用其它模塊提供的接口,。同時還為模塊創(chuàng)造了命名空間,,防止函數(shù)的命名沖突,。
export,import 命令
//test.js
export var name = 'Rainbow'
ES6將一個文件視為一個模塊,上面的模塊通過 export 向外輸出了一個變量,。一個模塊也可以同時往外面輸出多個變量,。
//test.js
var name = 'Rainbow';
var age = '24';
export {name, age};
定義好模塊的輸出以后就可以在另外一個模塊通過import 引用。
//index.js
import {name, age} from './test.js'
整體輸入,,module指令
//test.js
export function getName() {
return name;
}
export function getAge(){
return age;
}
通過 import * as 就完成了模塊整體的導(dǎo)入,。
import * as test form './test.js';
通過指令 module 也可以達到整體的輸入。
module test from 'test.js';
test.getName();
export default
不用關(guān)系模塊輸出了什么,,通過 export default 指令就能加載到默認模塊,,不需要通過 花括號來指定輸出的模塊,一個模塊只能使用 export default 一次
// default 導(dǎo)出
export default function getAge() {}
// 或者寫成
function getAge() {}
export default getAge;
// 導(dǎo)入的時候不需要花括號
import test from './test.js';
一條import 語句可以同時導(dǎo)入默認方法和其它變量.
import defaultMethod, { otherMethod } from 'xxx.js';
|