箭頭函數的語法
箭頭函數的語法多變,根據實際使用場景有多種形式。所有的變種都由函數參數、箭頭、函數體組成,根據使用的需求,參數和函數體可分別采取多種不同形式。舉個例子:
let reflect = value => value; // 實際上相當於: let reflect = function(value) { return value; };
當箭頭函數只有一個參數時,可以直接寫參數名,箭頭緊隨其后,箭頭右側的表達式被求值后便立即返回。即使沒有顯示的返回語句,這個箭頭函數也可以返回出傳入的第一個參數,不需要更多的語法鋪墊。
如果傳入兩個或兩個以上參數,要在參數的兩側添加一對小括號,就像這樣:
let sum = (num1, num2) => num1 + num2; // 實際上相當於: let sum = function(num1, num2) { return num1 + num2; };
如果函數沒有參數,也要在聲明的時候寫一組沒有內容的小括號,就像這樣:
let getName = () => 'Nicholas'; // 實際上相當於: let getName = function( ) { return 'Nicholas'; };
為函數編寫由多個表達式組成的更傳統的函數體,那么需要用花括號包裹函數體,並顯示地定義一個返回值,就像這樣:
let sum = (num1, num2) => { return num1 + num2; } // 實際上相當於: let sum = function(num1, num2) { return num1 + num2; };
如果想創建一個空函數,需要寫一對沒有內容的花括號,就像這樣:
let doNothing = () => {}; // 實際上相當於: let doNothing = function( ) {};
如果想讓箭頭函數向外返回一個對象字面量,則需要將該字面量包裹在小括號里。就像這樣:
let getTempItem = id => ({ id: id, name: 'Temp' }); // 實際上相當於: let getTempItem = function(id) { return { id: id, name: 'Temp' } };
創建立即執行函數表達式
只要將箭頭函數包裹在小括號里,就可以實現:
let person = ((name) => { return { getName: function( ) { return name; } }; })('Nicholas'); console.log(person.getName()); // "Nicholas" // 實際上相當於: let person = function(name) { return { getName: function( ) { return name; } }; }('Nicholas'); console.log(person.getName()); // "Nicholas"
箭頭函數沒有 this
函數內的 this
值可以根據函數調用上下文而改變,這有可能錯誤地影響其他對象。思考一下這個示例:
let PageHandle = { id: '123456', init: function( ) { document.addEventListener('click', function(event) { this.doSomething(event.type); // 拋出錯誤 }, false); }, doSomething: function(type) { console.log('Handling' + type + 'for' + this.id); } }
實際上,因為 this
綁定的是事件目標對象的引用(在這段代碼中引用的是document
),而沒有綁定 PageHandle
,切由於 this.doSomething()
在目標 document
中不存在,所以無法正常執行。
可以使用 bind()
方法顯示地將函數的this綁定到 PageHandle
上來修正這個問題,就像這樣:
let PageHandle = { id: '123456', init: function( ) { document.addEventListener('click', (function(event) { this.doSomething(event.type); // 沒有產生錯誤 }).bind(this), false); }, doSomething: function(type) { console.log('Handling' + type + 'for' + this.id); } }
箭頭函數中沒有 this
綁定,必須通過查找作用域鏈來決定其值。如果箭頭函數被箭頭函數包含,則 this
綁定的是最近一層非箭頭函數的 this
;否則 this
的值會被設置為全局對象。舉個例子:
let PageHandle = { id: '123456', init: function( ) { document.addEventListener('click', event => this.doSomething(event.type), false); }, doSomething: function(type) { console.log('Handling' + type + 'for' + this.id); } }
箭頭函數缺少正常函數所以擁有的 prototype
屬性,它的設計初衷是“即用即棄”,所有不能用它定義新的類型。如果嘗試通過 new
關鍵字調用箭頭函數,會報錯,就像這樣:
var MyType = () => {}, object = new MyType(); // 錯誤,不可以通過 new 關鍵字抵用箭頭函數
箭頭函數和數組
舉個例子:
var result = value.sort((a, b) => a - b); // 實際上相當於: var result = value.sort(function(a, b) { return a - b; })
箭頭函數沒有 arguments 綁定
箭頭函數沒有自己的 arguments
對象,且無論函數在哪個上下文中執行,箭頭函數始終可以訪問外圍函數的 arguments
對象。舉個例子:
function creatArrowFunctonReturnningFirstArg( ) { return () => arguments[0]; } var arrowFunction = creatArrowFunctonReturnningFirstArg(5); console.log(arrowFunction()); // 5