10個最佳ES6特性 ES7與ES8的特性

10個最佳ES6特性原文連接:https://blog.fundebug.com/201...
與ES8特性原文連接:https://blog.fundebug.com/201...
譯者按: 人生苦短,我用ES6。前端

原文: Top 10 ES6 Features Every Busy JavaScript Developer Must Knowvue

譯者: Fundebugreact

爲了保證可讀性,本文采用意譯而非直譯,而且對源代碼進行了大量修改。另外,本文版權歸原做者全部,翻譯僅用於學習。ios

小編推薦:Fundebug專一於JavaScript、微信小程序、微信小遊戲,Node.js和Java線上bug實時監控。真的是一個很好用的bug監控服務,衆多大佬公司都在使用。es6

ES6,正式名稱是ECMAScript2015,可是ES6這個名稱更加簡潔。ES6已經再也不是JavaScript最新的標準,可是它已經普遍用於編程實踐中。若是你還沒用過ES6,如今還不算太晚…編程

下面是10個ES6最佳特性,排名不分前後:axios

函數參數默認值
模板字符串
多行字符串
解構賦值
對象屬性簡寫
箭頭函數
Promise
Let與Const

模塊化小程序

1. 函數參數默認值

不使用ES6
爲函數的參數設置默認值:微信小程序

function foo(height, color)
{
    var height = height || 50;
    var color = color || 'red';
    //...
}

這樣寫通常沒問題,可是,當參數的布爾值爲false時,是會出事情的!好比,咱們這樣調用foo函數:數組

foo(0, "", "")
由於0的布爾值爲false,這樣height的取值將是50。同理color的取值爲‘red’。

使用ES6

function foo(height = 50, color = 'red')
{
    // ...
}

2. 模板字符串

不使用ES6
使用+號將變量拼接爲字符串:

var name = 'Your name is ' + first + ' ' + last + '.'
使用ES6
將變量放在大括號之中:

var name = Your name is ${first} ${last}.
ES6的寫法更加簡潔、直觀。

3. 多行字符串

不使用ES6
使用「nt」將多行字符串拼接起來:

var roadPoem = 'Then took the other, as just as fair,\n\t'
    + 'And having perhaps the better claim\n\t'
    + 'Because it was grassy and wanted wear,\n\t'
    + 'Though as for that the passing there\n\t'
    + 'Had worn them really about the same,\n\t'

使用ES6
將多行字符串放在反引號之間就行了:

var roadPoem = `Then took the other, as just as fair,
    And having perhaps the better claim
    Because it was grassy and wanted wear,
    Though as for that the passing there
    Had worn them really about the same,`

4. 解構賦值

不使用ES6
當須要獲取某個對象的屬性值時,須要單獨獲取:

var data = $('body').data(); // data有house和mouse屬性
var house = data.house;
var mouse = data.mouse;

使用ES6
一次性獲取對象的子屬性:

var { house, mouse} = $('body').data()

對於數組也是同樣的:

var [col1, col2]  = $('.column');

5. 對象屬性簡寫

不使用ES6
對象中必須包含屬性和值,顯得很是多餘:

var bar = 'bar';
var foo = function ()
{
    // ...
}

var baz = {
  bar: bar,
  foo: foo
};

使用ES6
對象中直接寫變量,很是簡單:

var bar = 'bar';
var foo = function ()
{
    // ...
}

var baz = { bar, foo };

6. 箭頭函數

不使用ES6
普通函數體內的this,指向調用時所在的對象。

function foo() 
{
    console.log(this.id);
}

var id = 1;

foo(); // 輸出1

foo.call({ id: 2 }); // 輸出2

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

var foo = () => {
  console.log(this.id);
}

var id = 1;

foo(); // 輸出1

foo.call({ id: 2 }); // 輸出1

7. Promise

不使用ES6
嵌套兩個setTimeout回調函數:

setTimeout(function()
{
    console.log('Hello'); // 1秒後輸出"Hello"
    setTimeout(function()
    {
        console.log('Fundebug'); // 2秒後輸出"Fundebug"
    }, 1000);
}, 1000);

使用ES6
使用兩個then是異步編程串行化,避免了回調地獄:

var wait1000 = new Promise(function(resolve, reject)
{
    setTimeout(resolve, 1000);
});

wait1000
    .then(function()
    {
        console.log("Hello"); // 1秒後輸出"Hello"
        return wait1000;
    })
    .then(function()
    {
        console.log("Fundebug"); // 2秒後輸出"Fundebug"
    });

8. Let與Const

使用Var
var定義的變量未函數級做用域:

{
  var a = 10;
}

console.log(a); // 輸出10

使用let與const
let定義的變量爲塊級做用域,所以會報錯:(若是你但願實時監控JavaScript應用的錯誤,歡迎無償使用Fundebug)

{
  let a = 10;
}

console.log(a); // 報錯「ReferenceError: a is not defined」
const與let同樣,也是塊級做用域。

9. 類

不使用ES6
使用構造函數建立對象:

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

var p = new Point(1, 2);

console.log(p.add()); // 輸出3

使用ES6
使用Class定義類,更加規範,且你可以繼承:

class Point
{
    constructor(x, y)
    {
        this.x = x;
        this.y = y;
    }

    add()
    {
        return this.x + this.y;
    }
}

var p = new Point(1, 2);

console.log(p.add()); // 輸出3

10. 模塊化

JavaScript一直沒有官方的模塊化解決方案,開發者在實踐中主要採用CommonJS和AMD規範。而ES6制定了模塊(Module)功能。

不使用ES6
Node.js採用CommenJS規範實現了模塊化,而前端也能夠採用,只是在部署時須要使用Browserify等工具打包。這裏不妨介紹一下CommenJS規範。

module.js中使用module.exports導出port變量和getAccounts函數:

module.exports = {
  port: 3000,
  getAccounts: function() {
    ...
  }
}

main.js中使用require導入module.js:

var service = require('module.js')
console.log(service.port) // 輸出3000

使用ES6
ES6中使用export與import關鍵詞實現模塊化。

module.js中使用export導出port變量和getAccounts函數:

export var port = 3000
export function getAccounts(url) {
  ...
}

main.js中使用import導入module.js,能夠指定須要導入的變量:

import {port, getAccounts} from 'module'
console.log(port) // 輸出3000

也能夠將所有變量導入:

import * as service from 'module'
console.log(service.port) // 3000

Es7與Es8的特性

ES7只有2個特性:
includes()
指數操做符

ES8的一些特性:

Object.values()
Object.entries()
padStart()
padEnd()
Object.getOwnPropertyDescriptors()
函數參數列表結尾容許逗號
Async/Await
Array.prototype.includes()
不使用ES7
使用indexOf()驗證數組中是否存在某個元素,這時須要根據返回值是否爲-1來判斷:

let arr = ['react', 'angular', 'vue'];

if (arr.indexOf('react') !== -1)
{
    console.log('React存在');
}

使用ES7
使用includes()驗證數組中是否存在某個元素,這樣更加直觀簡單:

let arr = ['react', 'angular', 'vue'];

if (arr.includes('react'))
{
    console.log('React存在');
}

指數操做符
不使用ES7
使用自定義的遞歸函數calculateExponent或者Math.pow()進行指數運算:

function calculateExponent(base, exponent)
{
    if (exponent === 1)
    {
        return base;
    }
    else
    {
        return base * calculateExponent(base, exponent - 1);
    }
}

console.log(calculateExponent(7, 3)); // 輸出343
console.log(Math.pow(7, 3)); // 輸出343

使用ES7
使用指數運算符**,就像+、-等操做符同樣:

console.log(7**3);
Object.values()

不使用ES8
使用Object.keys()遍歷對象的屬性值,須要經過屬性名key去獲取屬性值:

let obj = {a: 1, b: 2, c: 3};

Object.keys(obj).forEach((key) =>
{
    console.log(obj[key]); // 輸出1, 2, 3
});

使用ES8
使用Object.values()遍歷對象的屬性值,無需使用使用屬性名:

let obj = {a: 1, b: 2, c: 3}
Object.values(obj).forEach(value =>
{
    console.log(value); // 輸出1, 2, 3
});
Object.entries()

不使用ES8
使用Object.keys()遍歷對象的屬性名和屬性值:

let obj = {a: 1, b: 2, c: 3};

Object.keys(obj).forEach((key) =>
{
    console.log(key + ": " + obj[key]); // 輸出a: 1, b: 2, c: 3
})

使用ES8
使用Object.entries()遍歷對象的屬性名和屬性值:

let obj = {a: 1, b: 2, c: 3};

Object.entries(obj).forEach(([key, value]) =>
{
    console.log(key + ": " + value); // 輸出a: 1, b: 2, c: 3
})
padStart()

不使用ES8

console.log('0.00')             
console.log('10,000.00')    
console.log('250,000.00')
輸出結果以下:

0.00
10,000.00
250,000.00

使用ES8
使用padStart()能夠在字符串前面填充指定的字符串:

console.log('0.00'.padStart(20))             
console.log('10,000.00'.padStart(20))    
console.log('250,000.00'.padStart(20))
輸出結果以下:

      0.00
 10,000.00
250,000.00
padEnd()

不使用ES8

console.log('0.00 ' + '0.00' )             
console.log('10,000.00 ' + '10,000.00' )    
console.log('250,000.00 ' + '250,000.00')
輸出以下:

0.00 0.00
10,000.00 10,000.00
250,000.00 250,000.00

使用ES8
使用padEnd()能夠在字符串後面填充指定的字符串:

console.log('0.00'.padEnd(20) + '0.00' )             
console.log('10,000.00'.padEnd(20) + '10,000.00' )    
console.log('250,000.00'.padEnd(20) + '250,000.00')
輸出以下:

0.00                0.00
10,000.00           10,000.00
250,000.00          250,000.00

Object.getOwnPropertyDescriptors()

azatsBooks對象的定義以下:

let azatsBooks = {
    books: ['React Quickly'],
    get latest()
    {
        let numberOfBooks = this.books.length;
        if (numberOfBooks == 0) return undefined;
        return this.books[numberOfBooks - 1];
    }
};

不使用ES8
使用Object.getOwnPropertyDescriptor()獲取單個屬性的屬性描述符。

獲取azatsBooks對象的books屬性的屬性描述符:

console.log(Object.getOwnPropertyDescriptor(azatsBooks, 'books'));

/** 輸出books屬性的屬性描述
[object Object] {
  configurable: true,
  enumerable: true,
  value: ["React Quickly"],
  writable: true
}
**/
獲取azatsBooks對象的lastest方法的屬性描述符:

console.log(Object.getOwnPropertyDescriptor(azatsBooks, 'latest'));

/** 輸出lastest方法的屬性描述
[object Object] {
  configurable: true,
  enumerable: true,
  get: function get latest() {
    let numberOfBooks = this.books.length
    if (numberOfBooks == 0) return undefined
    return this.books[numberOfBooks - 1]
  },
  set: undefined
}
**/

使用ES8
Object.getOwnPropertyDescriptors()至關於Object.getOwnPropertyDescriptor()的複數形式,能夠獲取對象的全部自身屬性的描述符:

console.log(Object.getOwnPropertyDescriptors(azatsBooks))

/** 輸出azatsBooks對象全部自身屬性的屬性描述
[object Object] {
  books: [object Object] {
    configurable: true,
    enumerable: true,
    value: ["React Quickly"],
    writable: true
  },
  latest: [object Object] {
    configurable: true,
    enumerable: true,
    get: function get latest() {
      let numberOfBooks = this.books.length
      if (numberOfBooks == 0) return undefined
      return this.books[numberOfBooks - 1]
    },
    set: undefined
  }
}
**/

函數參數列表結尾容許逗號
不使用ES8

var f = function(a,
  b,
  c,
  d // d以後不能帶逗號
   ) { 
  console.log(d)
}

使用ES8

var f = function(a,
  b,
  c,
  d, // d以後容許帶逗號
) { 
  console.log(d)
}

容許逗號以後,能夠避免一些沒必要要的報錯。(若是你但願實時監控JavaScript應用的錯誤,歡迎無償使用Fundebug)

Async/Await
使用Promise
使用Promise寫異步代碼,會比較麻煩:

axios.get(`/q?query=${query}`)
    .then(response => response.data)
    .then(data =>
    {
        this.props.processfetchedData(data);
    })
    .catch(error => console.log(error));

使用Async/Await
Async/Await使得異步代碼看起來像同步代碼,這正是它的魔力所在:

async fetchData(query) =>
{
    try
    {
        const response = await axios.get(`/q?query=${query}`);
        const data = response.data;
        return data;
    }
    catch (error)
    {
        console.log(error)
    }
}

fetchData(query).then(data =>
{
    this.props.processfetchedData(data)
})

Async/Await是寫異步代碼的新方式,之前的方法有回調函數和Promise。相比於Promise,它更加簡潔,而且處理錯誤、條件語句、中間值都更加方便,所以有望替代Promise,成爲新一代的一步代碼編寫方式。對細節感興趣的話,能夠查看Fundebug翻譯的《Async/Await替代Promise的6個理由》。

相關文章
相關標籤/搜索