箭頭函式就是個簡寫形式的函式表示式
,並且它擁有詞法作用域的this
值(即不會新產生自己作用域下的this,arguments
,super
和new.target
等物件)。此外,箭頭函式總是匿名的
。語法
基礎語法
(param1, param2, …, paramn) =>
(param1, param2, …, paramn) => expression
// equivalent to: =>
// 如果只有乙個引數,圓括號是可選的:
(singleparam) =>
singleparam =>
// 無引數的函式需要使用圓括號:
() =>
高階語法
// 返回物件字面量時應當用圓括號將其包起來:
params => ()
// 支援 rest parameters 和 default parameters:
(param1, param2, ...rest) =>
(param1 = defaultvalue1, param2, …, paramn = defaultvaluen) =>
// destructuring within the parameter list is also supported
var f = ([a, b] = [1, 2], = ) => a + b + c;
f(); // 6
描述
箭頭函式的引入有兩個方面的影響:一是更簡短的函式書寫,二是對this
的詞法解析。
在一些函式式程式設計模式裡,更短的函式書寫方式很受歡迎。試比較:
var a = [
"hydrogen",
"helium",
"lithium",
"beryllium"
];var a2 = a.map(function(s));
var a3 = a.map( s => s.length );
在箭頭函式出現之前,每個新定義的函式都有其自己的this值(例如,建構函式的 this 指向了乙個新的物件;嚴格模式下的函式的this
值為undefined
;如果函式是作為物件的方法被呼叫的,則其 this 指向了那個呼叫它的物件)。在物件導向風格的程式設計中,這被證明是非常惱人的事情。
function person() , 1000);
}var p = new person();
在 ecmascript 3/5 中,這個問題可以通過新增乙個變數來指向期望的this
物件,然後將該變數放到閉包中來解決
。
function person() , 1000);
}
除此之外,還可以使用bind函式,把期望的this
值傳遞給growup()
函式。
箭頭函式則會捕獲其所在上下文的this
值,作為自己的this
值,因此下面的**將如期執行。
function person(), 1000);
}var p = new person();
與 strict mode 的關係
考慮到this是詞法層面上的,嚴格模式中與this相關的規則都將被忽略。
var f = () => ;
f() === window; // 或全域性物件
嚴格模式的其他規則依然不變.
var adder = ,
addthrucall: function(a) ;
return f.call(b, a);
}};console.log(adder.add(1)); // 輸出 2
console.log(adder.addthrucall(1)); // 仍然輸出 2(而不是3 ——譯者注)
箭頭函式不會在其內部暴露出arguments物件:arguments.length
,arguments[0]
,arguments[1]
等等,都不會指向箭頭函式的 arguments,而是指向了箭頭函式所在作用域的乙個名為 arguments 的值(如果有的話,否則,就是 undefined)。
var arguments = 42;
var arr = () => arguments;
arr(); // 42
function foo()
foo(1); // 1
箭頭函式沒有自己的arguments
物件,不過在大多數情形下,rest引數可以給出乙個解決方案:
function foo()
foo(1); // 2
如上所述, 箭頭函式表示式對沒有方法名的函式是最合適的.讓我們看看當我們試著把它們作為方法時發生了什麼.
'use strict';
var obj =
}obj.b(); // prints undefined, window
obj.c(); // prints 10, object
箭頭函式沒有定義this繫結。
'use strict';
var obj = ;
object.defineproperty(obj, "b",
});
使用new操作符
箭頭函式不能用作構造器,和 new 一起用就會丟擲錯誤。
yield
關鍵字通常不能在箭頭函式中使用(except when permitted within functions further nested within it)。因此,箭頭函式不能用作generator函式。
請牢記,用params =>
這種簡單的語法返回乙個物件字面量是行不通的:
var func = () => ;
// calling func() returns undefined!
var func = () => };
// syntaxerror: function statement requires a name
這是因為花括號(即{}
)裡面的**被解析為宣告序列了(例如,foo
被認為是乙個 label, 而非物件字面量裡的鍵)。
所以,記得用圓括號把物件字面量包起來:
var func = () => ();
換行
箭頭函式在引數和箭頭之間不能換行哦
var func = ()
=> 1; // syntaxerror: expected expression, got '=>'
解析順序
在箭頭函式中的箭頭不是操作符(或者運算子,就像'+ -'那些), 但是 箭頭函式有特殊的解析規則就是:相比普通的函式, 隨著操作符優先順序不同互動也不同(建議看英文版)。
let callback;
callback = callback || function() {}; // ok
callback = callback || () => {}; // syntaxerror: invalid arrow-function arguments
callback = callback || (() => {}); // ok
示例
// 乙個空箭頭函式,返回 undefined
let empty = () => {};
(() => "foobar")() // 返回 "foobar"
var ****** = a => a > 15 ? 15 : a;
******(16); // 15
******(10); // 10
let max = (a, b) => a > b ? a : b;
var arr = [5, 6, 13, 0, 1, 18, 23];
var sum = arr.reduce((a, b) => a + b); // 66
var even = arr.filter(v => v % 2 == 0); // [6, 0, 18]
var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46]
// 更多簡明的promise鏈
promise.then(a => ).then(b => );
深入理解JavaScript閉包
一 什麼是閉包 多個 兩個或兩個以上 函式巢狀,當內部函式被儲存到外部時,將會生成閉包。內部函式在外面執行的時候一定能夠呼叫的了原來它在的那個函式環境裡的變數。閉包會導致原有作用域鏈不釋放,造成記憶體洩露。functiona var aaa 123 return b var glob 100 var...
深入理解javascript 基礎筆記1
通過var宣告 或未宣告的變數都會在全域性window,this上產生全域性變數。對於 var a b 0 來說,全域性變數a是不能被刪除的,隱式全域性變數b是可以刪除的 對於乙個系統的不同組成部分,如果都有相同命名的全域性變數名,如parta,partb都有乙個全域性變數result,後者會替換前...
javascript對閉包的深入理解
最近看了一些關於閉包的內容,自己總結了一下 function getfunction return result var result1 getfunction for var j 0 j 10 j 每乙個內部函式都會儲存著屬於自己的作用域鏈,而它自己的作用域鏈包括了自己的活動物件,外部函式的活動物...