ES6 箭頭函式你正確使用了嗎

歸子莫發表於2021-07-14

ES6 箭頭函式你正確使用了嗎

部落格說明

文章所涉及的資料來自網際網路整理和個人總結,意在於個人學習和經驗彙總,如有什麼地方侵權,請聯絡本人刪除,謝謝!

說明

在ES6中允許使用“箭頭”(=>)定義函式,所以在我們後續寫程式碼的過程中出現的很多的箭頭函式,因為真香!但是也帶來的一些問題,靈魂拷問,你真的瞭解箭頭函式嗎?因為不敢肯定作答,故此書。

箭頭函式

一個簡單箭頭函式
// es6
const hello = item => item;

// es5 上面的程式碼等同於
const hello = function (item) {
  return item;
};
用法(三大如果)

如果箭頭函式不需要引數或需要多個引數,就使用一個圓括號代表引數部分。

const hello = () => 'hello';

const sum = (num1, num2) => num1 + num2;

如果箭頭函式的程式碼塊部分多於一條語句,就要使用大括號將它們括起來,並且使用return語句返回。

const sum = (num1, num2) => { 
  let num = 0; 
  if(num1 && num2){
    num = num1 + num2;
  }
  return num;
}

如果箭頭函式直接返回一個物件,必須在物件外面加上括號,否則會報錯。

const getInfo = id => ({ id: id, name: "hello" });

四大注意點

以下四點可能被無數次的提及,並且出現在各大面試題當中,不錯,今天又來了一次。

  • 箭頭函式沒有自己的this物件
  • 不可以當作建構函式,不可以使用new命令
  • 不可以使用arguments物件,該物件在函式體內不存在。如果要用,可以用 rest 引數代替
  • 不可以使用yield命令,因此箭頭函式不能用作 Generator 函式

箭頭函式的this指向

對於普通函式來說,內部的this指向函式執行時所在的物件。箭頭函式沒有自己的this物件,內部的this就是定義時上層作用域中的this

箭頭函式內部的this指向是固定的,相比之下,普通函式的this指向是可變的。

將ES6轉成ES5

發現其實只是所謂的箭頭函式的this只是從外面”借“來的

// ES6
function foo() {
  setTimeout(() => {
    console.log('id:', this.id);
  }, 100);
}

// ES5
function foo() {
  var _this = this;

  setTimeout(function () {
    console.log('id:', _this.id);
  }, 100);
}

在setInterval中,其實是沒有this.s2的,所以它的值不會變化。

function test() {
  this.s1 = 0;
  this.s2 = 0;
  // 箭頭函式
  setInterval(() => this.s1++, 1000);
  // 普通函式
  setInterval(function () {
    this.s2++;
  }, 1000);
}

s1 // 1
s2 // 0

普通函式修改之後可以修改s2

// 普通函式
setInterval(function () {
	let _this = this;
  _this.s2++;
}, 1000);

在這裡也能看到箭頭函式的this的指向,可以發現箭頭函式非常適合來做回撥

不能作為建構函式

不能作為建構函式,這個好理解。因為箭頭函式根本沒有自己的this,拿甚構造?所以箭頭函式也就不能用作建構函式。也不能使用new關鍵詞。

不可以使用arguments物件

像this一樣,arguments指向外層函式的對應變數,像類似的兄弟還有supernew.target

function hello() {
  setTimeout(() => {
    console.log('args:', arguments);
  }, 1000);
}

hello(1,2,3,4)
// args: [1, 2, 3, 4]

也因為這個this的問題,箭頭函式也不能用call()apply()bind()這些方法去改變this的指向,因此箭頭函式的this是”靜態“的。

箭頭函式的好與壞

說到箭頭函式的this,導致這個沒有那個沒有,其實不然,在ES6之前的this物件一直是一個令人頭痛的問題,使用時小心翼翼,回撥一多,程式碼就糊了。正是因為這個”靜態“的this的出現,改善了這一些問題。

在使用箭頭函式的時候,要合理的利用箭頭函式的優劣,選擇合適的場景。在定義物件方法和動態繫結this的時候不要使用箭頭函式。

感謝

萬能的網路

阮一峰的ES6教程

以及勤勞的自己,個人部落格GitHub

微信公眾號

相關文章