ES6部分方法點評(一)

一直以來,我對ES6都不甚感興趣,一是由於在生產環境中使用ES5已經是到處碰壁,其次則是隻當這ES6是語法糖未曾重視。
只是最近學習react生態,用起babel來轉換jsx之餘,也難免碰到諸多用上ES6的教程、案例,所以便稍做學習。這一學習,便以爲這語法糖實在是甜,忍不住嚐鮮,因而記錄部分自覺對本身有用的方法在此。javascript

箭頭函數(Arrow Functions)

箭頭函數是一個典型的語法糖,即創造了一種新語法來簡化javascript中函數的寫法:java

// ES5
var selected = allJobs.filter(function (job) {
  return job.isSelected();
});
// ES6
var selected = allJobs.filter(job => job.isSelected());

上面這是函數只有一個形參的狀況,下面列舉函數有多個形參的狀況:react

// ES5
var total = values.reduce(function (a, b) {
  return a + b;
}, 0);
// ES6
var total = values.reduce((a, b) => a + b, 0);

語法大致是這樣:([函數的形參,多個參數則以逗號分隔]) => [函數返回的值/表達式]
另外,箭頭函數也可使用{}來引入函數塊語句,不過這樣的話其實就只是簡寫了function這一個單詞了,意義不是很大,下面放個例子:編程

// ES5
$("#confetti-btn").click(function (event) {
  playTrumpet();
  fireConfettiCannon();
});
// ES6
$("#confetti-btn").click(event => {
  playTrumpet();
  fireConfettiCannon();
});

對我來講,簡寫並不吸引我,吸引個人,是箭頭函數的一個重要特性:箭頭函數沒有它本身的this值,箭頭函數內的this值繼承自外圍做用域。數組


2016-05-31修改: @n͛i͛g͛h͛t͛i͛r͛e͛同窗指出babel

arrow function 不是「沒有本身的 this」,而是綁定了定義時的 context;這一特性等價於之前的
Function.prototype.bind

我翻查了一下MDN,裏面是這麼寫的:閉包

箭頭函數則會捕獲其所在上下文的 this 值,做爲本身的 this 值。

所以,@n͛i͛g͛h͛t͛i͛r͛e͛同窗的說法是有理的。函數式編程


這在編寫回調函數的時候就很是好用了,咱們不再須要利用閉包來保存this了(尤爲是,很容易忘記保存this而直接在回調函數裏用了this):函數

{
  add: function(piece) {},
  ...
  addAll: function addAll(pieces) {
    var self = this;
    _.each(pieces, function (piece) {
      self.add(piece);
    });
  },
  ...
}

// ES6
{
  add: function(piece) {},
  ...
  addAll: function addAll(pieces) {
    _.each(pieces, piece => this.add(piece));
  },
  ...
}

let

自ES6中let的出現,javascript終於迎來了塊級做用域({}、for、if)。學習


2016-05-31修改:
此處表達有誤,應爲:自ES6,javascript開始擁有塊級做用域,而let則是配合塊級做用域,做爲替代var的一個語法定義。


有了塊級做用域,不再用擔憂臨時變量污染到外層的變量了:

function f1() {
  let n = 5;
  if (true) {
    let n = 10;
  }
  console.log(n); // 5
}

const

const是用來定義常量的,一旦定義了就不可修改(一修改就報錯)。用途嘛,也比較單一,就是定義一下配置項什麼的,省得被團隊裏的愣頭青寫的代碼給瞎改了。


2016-05-31修改 @n͛i͛g͛h͛t͛i͛r͛e͛同窗提出一個「命名綁定」的概念,並舉出一個相應的例子:

const config = {};
config.env = 'development';  // 這不會報錯

config = {};  // 這纔會報錯

請恕我才疏學淺,尚不能理解「命名綁定」呀、函數式編程之類的。我對上面這個例子的理解是,config只是一個object的引用,不管這個object自己怎麼變化,只要config這個變量的「指向」沒變化,那就不會報錯。


destructuring

destructuring是解構的意思,ES6容許按照必定模式,從數組和對象中提取值,對變量進行賦值,這被稱爲解構(Destructuring)。來兩個例子看看你們就明白了。

'use strict';

// 數組的解構賦值
let [foo, [[bar], baz]] = [1, [[2], 3]];
console.log(foo); // 1
console.log(bar); // 2
console.log(baz); // 3

// 對象的解構賦值
var { foo, bar } = { foo: "aaa", bar: "bbb" };
console.log(foo);   // "aaa"
console.log(bar );  // "bbb"

// 字符串的解構賦值
const [a, b, c, d, e] = 'hello';
console.log(a + b + c + e); // 'hello'

跟箭頭函數同樣,也是個語法糖,那這是用在什麼地方呢?請不要着急,聽我細細道來:
在咱們封裝函數的時候,若是形參較多,爲了使用者不須要按順序來傳入參數,每每用一個object來承載全部的參數,例如這樣:

// 二逼青年寫法
function study(id, name, sex, grade, nickname, age, address) {
    console.log(id);
    console.log(name);
    console.log(sex);
    console.log(grade);
    console.log(nickname);
    console.log(age);
    console.log(address);
}
// 正常青年寫法
function study(params) {
    console.log(params.id);
    console.log(params.name);
    console.log(params.sex);
    console.log(params.grade);
    console.log(params.nickname);
    console.log(params.age);
    console.log(params.address);
}

這種作法,雖然說使用者是方便了,但寫函數的人卻麻煩了,每次用參數都要帶上params.,或者再寫個var id = params.id來讓後續的使用方便一些。
然而,有了destructuring後,咱們有了更方便的寫法:

function study({id, name, sex, grade, nickname, age, address}) {
    console.log(id);
    console.log(name);
    console.log(sex);
    console.log(grade);
    console.log(nickname);
    console.log(age);
    console.log(address);    
}
study({
    id: 1,
    name: '林有德',
    sex: '男',
    grade: '一年級',
    nickname: '布萊德',
    age: 12,
    address: '木馬號'
});

這樣一來,使用者用起來很方便,而函數內部又直接解構賦值到各變量上,用起來也方便多了。

相關文章
相關標籤/搜索