ES6常用的新特性總結

luckykun發表於2016-08-26

ES6是即將到來的新版本JavaScript語言的標準,他給我們帶來了更”甜”的語法糖(一種語法,使得語言更容易理解和更具有可讀性,也讓我們編寫程式碼更加簡單快捷),如箭頭函式(=>)、class等等。用一句話來說就是:

ES6給我們提供了許多的新語法和程式碼特性來提高javascript的體驗

不過遺憾的是,現在還沒有瀏覽器能夠很好的支援es6語法,點這裡檢視瀏覽器支援情況,所以我們在開發中還需要用babel進行轉換為CommonJS這種模組化標準的語法。

因為下面我會講到一些es6新特性的例子,如果想要執行試試效果的話,可以點這裡去測試es6的程式碼。

es6常用特性列舉

然後我下面簡單的介紹一些很常用的語法特性,如果想完整的瞭解ES6,我推薦大家點這裡

定義函式

我們先來看一個基本的新特性,在javascript中,定義函式需要關鍵字function,但是在es6中,還有更先進的寫法,我們來看:

es6寫法:

var human = {
    breathe(name) {   //不需要function也能定義breathe函式。
        console.log(name + ' is breathing...');
    }
};
human.breathe('jarson');   //輸出 ‘jarson is breathing...’

轉成js程式碼:

var human = {
    breathe: function(name) {
      console.log(name + 'is breathing...');
    }
};
human.breathe('jarson');

很神奇對不對?這樣一對比,就可以看出es6的寫法讓人簡單易懂。彆著急,下面還有更神奇的。

建立類

我們知道,javascript不像java是物件導向程式設計的語言,而只可以說是基於物件程式設計的語言。所以在js中,我們通常都是用function和prototype來模擬這個概念。

但是現在有了es6,我們可以像java那樣’明目張膽’的建立一個類了:

class Human {
    constructor(name) {
        this.name = name;
      }
     breathe() {
        console.log(this.name + " is breathing");
      }
}
var man = new Human("jarson");
man.breathe();    //jarson is breathing

上面程式碼轉為js格式:

function Human(name) {
    this.name = name;
    this.breathe = function() {
        console.log(this.name + ' is breathing');
    }
}
var man = new Human('jarson');
man.breathe();    //jarson is breathing

所以我們看到,我們可以像java那樣語義化的去建立一個類。另外,js中的繼承父類,需要用prototype來實現。那麼在es6中,又有什麼新的方法來實現類的繼承呢?繼續看:

假如我們要建立一個Man類繼承上面的Human類,es6程式碼:

class Man extends Human {
      constructor(name, sex) {
        super(name);
          this.sex = sex;
      }
      info(){
          console.log(this.name + 'is ' + this.sex);
    }
}
var xx = new Man('jarson', 'boy');
xx.breathe();   //jarson is breathing
xx.info();   //arsonis boy

程式碼很簡單,不作贅述,可以使用文章裡提到的線上工具去試試效果就能明白了。需要注意的是:super()是父類的建構函式。

模組

在ES6標準中,javascript原生支援module了。將不同功能的程式碼分別寫在不同檔案中,各模組只需匯出(export)公共介面部分,然後在需要使用的地方通過模組的匯入(import)就可以了。下面繼續看例子:

內聯匯出

ES6模組裡的物件可在建立它們的宣告中直接匯出,一個模組中可無數次使用export。

先看模組檔案app.js

export class Human{
    constructor(name) {
        this.name = name;
    }
    breathe() {
        console.log(this.name + " is breathing");
    }
}  
export function run(){  
    console.log('i am runing');
}
function eat() {
    console.log('i am eating');
}

例子中的模組匯出了兩個物件:Human類和run函式, eat函式沒有匯出,則仍為此模組私有,不能被其他檔案使用。

匯出一組物件

另外,其實如果需要匯出的物件很多的時候,我們可以在最後統一匯出一組物件。

更改app.js檔案:

class Human{
    constructor(name) {
        this.name = name;
    }
    breathe() {
        console.log(this.name + " is breathing");
    }
}  
function run(){  
    console.log('i am runing');
}
function eat() {
    console.log('i am eating');
}
export {Human, run};

這樣的寫法功能和上面一樣,而且也很明顯,在最後可以清晰的看到匯出了哪些物件。

Default匯出

匯出時使用關鍵字default,可將物件標註為default物件匯出。default關鍵字在每一個模組中只能使用一次。它既可以用於內聯匯出,也可以用於一組物件匯出宣告中。

檢視匯出default物件的語法:

...   //建立類、函式等等
export default {  //把Human類和run函式標註為default物件匯出。
    Human,  
    run  
};

無物件匯入

如果模組包含一些邏輯要執行,且不會匯出任何物件,此類物件也可以被匯入到另一模組中,匯入之後只執行邏輯。如:

import './module1.js';

匯入預設物件

使用Default匯出方式匯出物件,該物件在import宣告中將直接被分配給某個引用,如下例中的”app”。

import app from './module1.js';

上面例子中,預設./module1.js檔案只匯出了一個物件;若匯出了一組物件,則應該在匯入宣告中一一列出這些物件,如:

import {Human, run} from './app.js'

let與const

在我看來,在es6新特性中,在定義變數的時候統統使用let來代替var就好了,const則很直觀,用來定義常量,即無法被更改值的變數。

for (let i=0;i<2;i++) {
    console.log(i);  //輸出: 0,1
}

箭頭函式

ES6中新增的箭頭操作符=>簡化了函式的書寫。操作符左邊為輸入的引數,而右邊則是進行的操作以及返回的值,這樣的寫法可以為我們減少大量的程式碼,看下面的例項:

let arr = [6, 8, 10, 20, 15, 9];
arr.forEach((item, i) => console.log(item, i));
let newArr = arr.filter((item) => (item<10));
console.log(newArr); //[6, 8, 9];

上面的(item, i)就是引數,後面的console.log(item, i)就是回到函式要執行的操作邏輯。

上面程式碼轉為js格式:

var arr = [6, 8, 10, 20, 15, 9];
arr.forEach(function(item, i) {
    return console.log(item, i);
});
var newArr = arr.filter(function(item) {
    return (item < 10);
});
console.log(newArr);

字串模版

ES6中允許使用反引號 ` 來建立字串,此種方法建立的字串裡面可以包含由美元符號加花括號包裹的變數${vraible}。看一下例項就會明白了:

//產生一個隨機數
let num = Math.random();
//將這個數字輸出到console
console.log(`your num is ${num}`);

解構

若一個函式要返回多個值,常規的做法是返回一個物件,將每個值做為這個物件的屬性返回。在ES6中,利用解構這一特性,可以直接返回一個陣列,然後陣列中的值會自動被解析到對應接收該值的變數中。我們來看例子:

function getVal() {
    return [1, 2];
}
var [x,y] = getVal(); //函式返回值的解構
console.log('x:'+x+', y:'+y);   //輸出:x:1, y:2

預設引數

現在可以在定義函式的時候指定引數的預設值了,而不用像以前那樣通過邏輯或操作符來達到目的了。

function sayHello(name){
    var name=name||'tom';    //傳統的指定預設引數的方式
    console.log('Hello '+name);
}
//運用ES6的預設引數
function sayHello2(name='tom'){  //如果沒有傳這個引數,才會有預設值,
    console.log(`Hello ${name}`);
}
sayHello();//輸出:Hello tom
sayHello('jarson');//輸出:Hello jarson
sayHello2();//輸出:Hello tom
sayHello2('jarson');//輸出:Hello jarson

注意: sayHello2(name='tom')這裡的等號,意思是沒有傳這個引數,則設定預設值,而不是給引數賦值的意思。

Proxy

Proxy可以監聽物件身上發生了什麼事情,並在這些事情發生後執行一些相應的操作。一下子讓我們對一個物件有了很強的追蹤能力,同時在資料繫結方面也很有用處。

//定義被監聽的目標物件
let engineer = { name: 'Joe Sixpack', salary: 50 };
//定義處理程式
let interceptor = {
      set(receiver, property, value) {
        console.log(property, 'is changed to', value);
        receiver[property] = value;
      }
};
//建立代理以進行偵聽
engineer = new Proxy(engineer, interceptor);
//做一些改動來觸發代理
engineer.salary = 70;//控制檯輸出:salary is changed to 70

對於處理程式,是在被監聽的物件身上發生了相應事件之後,處理程式裡面的方法就會被呼叫。

結語

總的來說,雖然支援es6的情況到目前還不是很樂觀,但es6的新語法特性讓前端和後端的差異越來越小了,這是一個新時代的開始,我們必須要了解這些新的前沿知識,才能跟上時代的步伐。

相關文章