摘要:箭頭函數沒有綁定,意味著箭頭函數內部的值只能通過查找作用域鏈來確定。無論此后箭頭函數在何處執行,該對象都是可用的。
箭頭函數
es6的箭頭函數,顧名思義箭頭函數是使用一個箭頭( => )來定義的函數,這很容易理解但是它有很多行為與傳統的js函數不同:
沒有 this 、 super 、 arguments 。
不能被使用 new 調用: 箭頭函數沒有 [[Construct]] 方法,因此不能被用為構造函數,使用 new 調用箭頭函數會拋出錯誤。
沒有原型: 既然不能對箭頭函數使用 new ,那么它也不需要原型,也就是沒有prototype 屬性。
不能更改 this : this 的值在函數內部不能被修改,在函數的整個生命周期內其值會保持不變。
沒有 arguments 對象: 既然箭頭函數沒有 arguments 綁定,你必須依賴于具名參數或剩余參數來訪問函數的參數
不允許重復的具名參數: 箭頭函數不允許擁有重復的具名參數,無論是否在嚴格模式下;而相對來說,傳統函數只有在嚴格模式下才禁止這種重復
箭頭函數的語法var reflect = value => value; // 有效等價于: var reflect = function(value) { return value; };
函數需要傳入多個參數:
var sum = (num1, num2) => num1 + num2; // 有效等價于: var sum = function(num1, num2) { return num1 + num2; };
如果函數沒有任何參數,那么在聲明時就必須使用一對空括號,就像這樣:
var getName = () => "Nicholas"; // 有效等價于: var getName = function() { return "Nicholas"; };
你基本可以將花括號內部的代碼當做傳統函數那樣對待,除了 arguments 對象不可用之外。
若你想創建一個空函數,就必須使用空的花括號,就像這樣:
var doNothing = () => {}; // 有效等價于: var doNothing = function() {};
花括號被用于表示函數的主體,它在你至今看到的例子中都工作正常。但若箭頭函數想要從
函數體內向外返回一個對象字面量,就必須將該字面量包裹在圓括號內,例如:
var getTempItem = id => ({ id: id, name: "Temp" }); // 有效等價于: var getTempItem = function(id) { return { id: id, name: "Temp" }; };沒有this綁定
JS 最常見的錯誤領域之一就是在函數內的 this 綁定。由于一個函數內部的 this 值可以
被改變,這取決于調用該函數時的上下文,因此完全可能錯誤地影響了一個對象,盡管你本
意是要修改另一個對象。
箭頭函數沒有 this 綁定,意味著箭頭函數內部的 this 值只能通過查找作用域鏈來確定。
如果箭頭函數被包含在一個非箭頭函數內,那么 this 值就會與該函數的相等;否則,
this 值就會是全局對象(在瀏覽器中是 window ,在 nodejs 中是 global )。
盡管箭頭函數沒有自己的 arguments 對象,但仍然能訪問包含它的函數的 arguments 對
象。無論此后箭頭函數在何處執行,該對象都是可用的。例如:
function createArrowFunctionReturningFirstArg() { return () => arguments[0]; } var arrowFunction = createArrowFunctionReturningFirstArg(5); console.log(arrowFunction()); // 5也像對其他函數那樣,你仍然可以對箭頭函數使用 call() 、 apply() 與 bind() 方法,雖
然函數的 this 綁定并不會受影響。這里有幾個例子:
var sum = (num1, num2) => num1 + num2; console.log(sum.call(null, 1, 2)); // 3 console.log(sum.apply(null, [1, 2])); // 3 var boundSum = sum.bind(null, 1, 2); console.log(boundSum()); // 3尾調用優化
在 ES6 中對函數最有趣的改動或許就是一項引擎優化,它改變了尾部調用的系統。尾調用(
tail call )指的是調用函數的語句是另一個函數的最后語句,就像這樣:
function doSomething() { return doSomethingElse(); // 尾調用 }
在 ES5 引擎中實現的尾調用,其處理就像其他函數調用一樣:一個新的棧幀( stack frame
)被創建并推到調用棧之上,用于表示該次函數調用。這意味著之前每個棧幀都被保留在內
存中,當調用棧太大時會出問題。
那什么時候不會被優化呢/
一個小改動——不返回結果(缺少return),就會產生一個無法被優化的函數:
"use strict"; function doSomething() { // 未被優化:缺少 return doSomethingElse(); }
如果你的函數在尾調用返回結果之后進行了額外操作,那么該函數也無法被優化:
"use strict"; function doSomething() { // 未被優化:在返回之后還要執行加法 return 1 + doSomethingElse(); }
關閉優化的另一個常見方式,是將函數調用的結果儲存在一個變量上,之后才返回了結果,就像這樣:
"use strict"; function doSomething() { // 未被優化:調用并不在尾部 var result = doSomethingElse(); return result; }
本例之所以不能被優化,是因為 doSomethingElse() 的值并沒有立即被返回。
使用閉包或許就是需要避免的最困難情況,因為閉包能夠訪問上層作用域的變量,會導致尾調用優化被關閉。例如:
"use strict"; function doSomething() { var num = 1, func = () => num; // 未被優化:此函數是閉包 return func(); }
"use strict";
function doSomething() {
var num = 1,
func = () => num;
// 未被優化:此函數是閉包
return func();
}
此例中閉包 func() 需要訪問局部變量 num ,雖然調用 func() 后立即返回了其結果,但 是對于 num 的引用導致優化不會發生.
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109291.html
摘要:特性介紹箭頭函數是新增的特性之一,它為這門語言提供了一種全新的書寫函數的語法。用生成的函數會定義一個自己的,而箭頭函數沒有自己的,而是會和上一層的作用域共享。 本文同步自我得博客:http://www.joeray61.com JS中的箭頭 箭頭在JS里并不算是個新鮮的玩意兒,一直以來,JS都支持-->這樣的箭頭。 很早的時候有些瀏覽器還不支持JS,當時的人們為了兼容這些瀏覽器,需要這...
摘要:回顧我們先來回顧下箭頭函數的基本語法。主要區別包括沒有箭頭函數沒有,所以需要通過查找作用域鏈來確定的值。箭頭函數并沒有方法,不能被用作構造函數,如果通過的方式調用,會報錯。 回顧 我們先來回顧下箭頭函數的基本語法。 ES6 增加了箭頭函數: let func = value => value; 相當于: let func = function (value) { return ...
摘要:使用或調用由于已經在詞法層面完成了綁定,通過或方法調用一個函數時,只是傳入了參數而已,對并沒有什么影響箭頭函數不會在其內部暴露出參數等等,都不會指向箭頭函數的,而是指向了箭頭函數所在作用域的一個名為的值如果有的話,否則,就是。 ES6之箭頭函數 標簽(空格分隔): 未分類 返回值 單行函數體默認返回改行計算結果, 多行需要指定返回值 let c = (a,b)=>a+b; conso...
摘要:使用或調用由于已經在詞法層面完成了綁定,通過或方法調用一個函數時,只是傳入了參數而已,對并沒有什么影響箭頭函數不會在其內部暴露出參數等等,都不會指向箭頭函數的,而是指向了箭頭函數所在作用域的一個名為的值如果有的話,否則,就是。 ES6之箭頭函數 標簽(空格分隔): 未分類 返回值 單行函數體默認返回改行計算結果, 多行需要指定返回值 let c = (a,b)=>a+b; conso...
摘要:使用或調用由于已經在詞法層面完成了綁定,通過或方法調用一個函數時,只是傳入了參數而已,對并沒有什么影響箭頭函數不會在其內部暴露出參數等等,都不會指向箭頭函數的,而是指向了箭頭函數所在作用域的一個名為的值如果有的話,否則,就是。 ES6之箭頭函數 標簽(空格分隔): 未分類 返回值 單行函數體默認返回改行計算結果, 多行需要指定返回值 let c = (a,b)=>a+b; conso...
閱讀 3096·2021-02-22 17:12
閱讀 719·2019-08-30 15:55
閱讀 3078·2019-08-30 15:54
閱讀 1384·2019-08-29 16:56
閱讀 1862·2019-08-29 15:13
閱讀 1716·2019-08-29 13:19
閱讀 601·2019-08-26 13:40
閱讀 2822·2019-08-26 10:26