快速瞭解ES6

ECMAScript6(簡稱ES6),是JavaScript的下一代標準,由於ES6是在2015年發佈的,因此又稱ECMAScript2015(ES6 === ECMAScript2015)html

目前不是全部的瀏覽器都徹底兼容ES6,但不少程序猿已經開始使用ES6了,因此瞭解並逐步掌握ES6,甚至在你的項目中使用ES6,是很是有必要的,至少也要看得懂小夥伴寫的ES6代碼吧?編程

在說ES6以前,咱們先來了解下Babel,這是個什麼鬼?它是一個普遍使用的ES6轉碼器,能夠將咱們寫的ES6代碼轉換成能在當前全部瀏覽器中執行的ES5代碼。你能夠在你習慣使用的工具中集成Babel,方便它來工做,具體使用請查看Babel官網(http://babeljs.io)數組

下面咱們來看下最經常使用的一些ES6特性:瀏覽器

  • let,const
  • class,extends,super
  • arrow functions
  • template string
  • destructuring
  • default
  • rest arguments

let,const

let是用來聲明變量的,與var類似,const是定義常量的。咱們先來看下面的例子緩存

while (true) {
    var name = 'obama';
    console.log(name);        //obama
    break;
}

console.log(name);            //obama

在ES5中只有全局做用域和函數做用域,沒有塊級做用域,因此上面的代碼中,while循環體內的name變量覆蓋了上面聲明的全局name變量,最後輸出的就是被覆蓋的變量值。而let爲JavaScript增長了塊級做用域,用它聲明的變量只在當前的代碼塊內有效。babel

let name = 'zach';
while (true) {
    let name = 'obama';
    console.log(name);            //obama
    break;
}

console.log(name);                //zach

另一個問題,就是計數循環閉包

var a = [];
for (var i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    }
}
a[6]();        //10

用var定義的i值,成了全局變量,會致使最後的i值是最後一輪循環完成後的值,而使用let就不會有這個問題。app

var a = [];
for (let i = 0; i < 10; i++) {
    a[i] = function () {
        console.log(i);
    }
}
a[6]();        //6

下面咱們再來看個例子,頁面上有5個類名相同的元素,咱們經過點擊這些元素,分別彈出他們在集合中的序號編程語言

var clickBoxs = documnet.querySelectorAll('clickBox');
for (var i = 0; i < clickBoxs.length; i++) {
    clickBoxs[i].onclick = function () {
        alert(i);
    }
}

很不幸,每次彈出的都是5.for循環中用var定義的i,已是全局變量,在執行彈出時,實際上i已經累加到了5,若是咱們將var換成let,就能夠在每次點擊的時候獲得咱們想要的結果。函數

再來想一想如何使用閉包來解決這個問題呢?

function iteratorFactory (i) {
    var onclick = function (e) {
        alert(i);
    }
    return onclick;
}

var clickBoxs = document.querySelectorAll('clickBox');
for (var i = 0; i < clickBoxs.length; i++) {
    clickBoxs[i].onclick = iteratorFactory(i);
}

const用來聲明常量,一旦聲明,常量的值是不能被改變的。

const PI = Math.PI;

###class,extends,super

這三個特性讓咱們從JavaScript的原型面向對象中解脫出來,它們讓JavaScript具備了像傳統高級編程語言那樣的寫法。

class Animal {
    constructor () {
        this.type = 'animal';
    }

    says (message) {
        console.log(this.type + ' says ' + message);
    }
}

let animal = new Animal();
animal.says('hello');        //animal says hello

class Cat extends Animal {
    constructor () {
        super();
        this.type = 'cat';
    }
}

let cat = new Cat();
cat.says('hello');        //cat says hello

上面的代碼首先定義了一個class,裏面有個constructor,這是構造函數,this關鍵字指向當前類的實例對象。 class之間能夠經過extends關鍵字實現繼承,上面的代碼中,Cat類經過extends繼承了Animal類的全部屬性和方法。 在子類中的constructor中,必須調用super方法,這是爲了繼承父類中的this。

arrow function

箭頭函數,這是ES6最經常使用的特性,用它來寫function比ES5的更加簡介和清晰。

function(i){return i + 1;}        //ES5
(i) => i + 1;                    //ES6

若是有多行代碼或代碼比較複雜的,須要使用{}把代碼包裹起來

function (x, y) {
    x++;
    y--;
    return x + y;
}

(x, y) => {x++; y--; return x + y;}

箭頭函數除了在寫法上更加簡潔以外,還有一個功能,更加明確了this的指向

class Animal {
    constructor () {
        this.type = 'animal';
    }

    says (message) {
        setTimeout (function () {
           console.log(this.type + ' says ' + message); 
        },1000);
    }
}

var animal = new Animal();
animal.says('hi');            //undefined says hi

上面的例子運行後,獲得的結果是undefined says hi,跟咱們預想的不同,是由於在setTimeout中,this已經指向了全局。如今,咱們有兩個傳統的方法來解決

第一種,將this傳遞給self,也就是將this對象緩存起來

says (message) {
    var self = this;
    setTimeout(function () {
        console.log(self.type + ' says ' + message);
    }, 1000);
}

第二種,使用bind(this)

says (message) {
    setTimeout(function () {
        console.log(this.type + ' says ' + message);
    }.bind(this), 1000);
}

OK,如今咱們有了箭頭函數,就不用這麼麻煩了。

class Animal {
    constructor () {
        this.type = 'animal';
    }

    says (message) {
        setTimeout(() => {
            console.log(this.type + ' says ' + message);
        }, 1000);
    }
}

var animal = new Animal();
animal.says('hi');            //animal says hi

使用箭頭函數時,函數體內的this就是定義時所在的對象,而不是使用時的對象。

template string

這玩意叫模板變量,它有什麼用呢? 當咱們須要在JS中插入大量的html內容時,傳統的寫法很麻煩,因此咱們常常會引入一些模板工具庫,咱們先來看下下面的代碼

$('#result').append(
    "There are <b>" + basket.count + "</b>" + 
    "items in your basket, " + 
    "<em>" + basket.onSale +
    "</em> are on sale!"
);

咱們須要用一大堆的‘+’來連接文本和變量,而有了ES6的模板變量後,咱們能夠這樣寫

$("#result").append(`
    There are <b>${basket.count}</b> items
    in your basket, <em>${basket.onSale}</em>
    are on sale!
`);

咱們用反引號" ` "來標示起始和結束,用" ${} "來引用變量,並且全部的空格和縮進都會被保留。

destructuring

ES6容許按照必定的模式,從數組和對象中取值,對變量進行賦值,這被稱爲解構(Destructuring)。

let cat = 'ken';
let dog = 'lili';
let zoo = {cat: cat, dog: dog};
console.log(zoo);                //Object {cat: "ken", dog: "lili"}

在ES6中,咱們能夠這樣寫

let cat = 'ken';
let dog = 'lili';
let zoo = {cat, dog};
console.log(zoo);            //Object {cat: "ken", dog: "lili"}

反過來能夠這麼寫

let dog = {type: 'animal', many: 2};
let {type, many} = dog;
console.log(type, many);                //animal 2

default, rest

default就是默認值的意思,若是在調用函數時候沒有傳參數,傳統作法是加上這麼一句,type = type || 'cat' 來指定默認值

function animal (type) {
    type = type || 'cat';
    console.log(type);
}

animal();                //cat

若是用ES6,就能夠這樣寫

function animal (type = 'cat') {
    console.log(type);
}

animal();

rest的語法也很簡單,看例子

function animals(...types) {
    console.log(types)
}

animals('cat', 'dog', 'fish');            //['cat', 'dog', 'fish']

若是不適用ES6的語法,那麼咱們必須使用ES5的arguments

以上就是ES6中最經常使用的語法,能夠說這20%的語法在使用中佔了80%的使用率。

未完,待續...

相關文章
相關標籤/搜索