JavaScript - ES6 - 箭頭函式
ES6
開始可以使用箭頭 =>
來定義涵式,但與原先的函式在某些情況並不完全相同,在這篇文章中會探討箭頭函式的寫法與傳統函式的差異
基本寫法
正常寫法,省略
function
,使用箭頭=>
1
2
3
4
5
6var fnc = function (e){
return 'Hello' + e;
}
var fnc = (e) => {
return 'Hello' + e ;
}如果只有內容只有一行,可以省略 “大括號”
{ }
和return
,並且自動回傳1
var fnc = (e) => 'Hello' + e;
如果只有 “一個參數”,可以省略 “小括號”
( )
1
var fnc = e => 'Hello' + e;
如果 “沒有參數” 或 “多個參數”,就一定要有 “小括號”
( )
1
2var fnc = () => 'Hello';
var fnc2 = (num1, num2) => num1 + num2;
沒有 arguments 參數
一般函式被呼叫時,都會產生一個 argument
物件,這個物件的內容就是我們帶入的 “參數”,而箭頭函式中是沒有 arguments
物件的
1 | var fnc = function (num1, num2){ |
this 差異
傳統函式 :
this
的值是動態的,由呼叫這個函式的擁有物件object
而定箭頭函式 :
this
的值綁定到其定義時所在的物件而定,也就是由周邊的作用域而定1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23var name = '我是全域';
var test = {
name: '我是作用域',
callName: function (){
console.log("1", this.name); // 1 我是作用域
setTimeout(() => {
console.log("2", this.name); // 2 我是作用域
console.log("3", this); // 3 test 這個物件
}, 100);
},
callName2: () => {
console.log("4", this.name); // 4 我是全域
setTimeout(() => {
console.log("5", this.name); // 5 我是全域
console.log("6", this); // 6 window 物件
}, 100);
}
}
test.callName();
test.callName2();由以上範例可以看到,傳統函式
function
的this
指的是這個函式的擁有物件test
,而箭頭函式在全域被宣告定義,所以其 this 自然指向最高級物件 window而外層的 “函式” 並不回影響箭頭函式的
this
原先指向的window
,外層的 “物件” 才會使箭頭函式的this
指向這個物件1
2
3
4
5
6
7
8
9
10
11
12
13var func = function (){
var func2 = function (){
setTimeout(() => {
console.log(this);
}, 10);
};
var func3 = {
func4: func2
}
func2(); // window 物件
func3.func4(); // func3 這個物件
}
func();由上範例可以看到,如果 “不是” 建立在 “物件” 內的箭頭函式,就不會影響箭頭函式的
this
- func() : 最外層的函式,不會影響內部箭頭函式的
this
- func2() : 第二層的函式,也不會影響內部箭頭函式的
this
- func3() : 為一個物件,內部箭頭函式的
this
就會指向這個物件
- func() : 最外層的函式,不會影響內部箭頭函式的
特殊的情況
內建函式 call
、apply
和 bind
1 | const obj = { a: 1 } |
func1
: 透過call
呼叫給定this
,所以this
自然指向obj
這個物件func2
: 箭頭函式沒有宣告在物件內部,所以this
還是指向window
func3
: 傳統函式的this
依據呼叫的方式,可以看成是window.setTimeout
,所以this
指向window
func4
: 因為外層func4
的this
被指定為obj
,所以setTimeout
內的箭頭函式會在obj
中被宣告func5
: 因為外層func5
在全域宣告,所以this
自然指向window,setTimeout
內箭頭函式的this
也會指向 window`
不能用在建構式函式
由於箭頭函式的 this
是在其所定義的物件下建立,所以不能像 function
一樣作為建構式的函式,直接使用 new
會出現錯誤
1 | const test = (num) => { |
DOM 事件的監聽
在 DOM
事件監聽的情況下,函式的 this
應該指向這個 DOM
元素本身,但箭頭函式的 this
依然會指向定義其所在的物件 window
,所以不適用於這類情況
1 | var btn = document.querySelector('.btn'); |
使用建議
- 物件內的函式可以優先使用,因為傳統函式以往的做法會先將
this
賦予再另一個變數上,以記錄當下的this
1 | var test = { |
- 雖然只有一個參數時可以省略 “小括號”
( )
,但還是建議都加上,避免意外錯誤