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
指向外層函式的對應變數,像類似的兄弟還有super
、new.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教程