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