JS箭頭函數(shù)和常規(guī)函數(shù)之間的區(qū)別實(shí)例分析【 5 個(gè)區(qū)別】
本文實(shí)例講述了JS箭頭函數(shù)和常規(guī)函數(shù)之間的區(qū)別。分享給大家供大家參考,具體如下:
在 JavaScript 中,你可以通過(guò)多種方式去定義函數(shù)。
第一種常用的方法是使用關(guān)鍵字 function
:
// 函數(shù)聲明 function greet(who) { return `Hello, ${who}!`; } // 函數(shù)表達(dá)式 const greet = function(who) { return `Hello, ${who}`; }
代碼中的函數(shù)聲明和函數(shù)表達(dá)式被稱為“常規(guī)函數(shù)”。
從 ES2015 開(kāi)始,第二種可用的方法是 箭頭函數(shù) 語(yǔ)法:
const greet = (who) => { return `Hello, ${who}!`; }
雖然兩者的語(yǔ)法都能夠定義函數(shù),但是在開(kāi)發(fā)時(shí)該怎么選擇呢?這是個(gè)好問(wèn)題。
在本文中,我將展示兩者之間的主要區(qū)別,以供你能夠根據(jù)需要選擇正確的語(yǔ)法。
1. this 值
1.1常規(guī)函數(shù)
在常規(guī) JavaScript 函數(shù)內(nèi)部,this
值(即執(zhí)行上下文)是動(dòng)態(tài)的。
動(dòng)態(tài)上下文意味著 this
的值取決于如何調(diào)用函數(shù)。在 JavaScript 中,有 4 種調(diào)用常規(guī)函數(shù)的方式。
在簡(jiǎn)單調(diào)用過(guò)程中,this
的值等于全局對(duì)象(如果函數(shù)在嚴(yán)格模式下運(yùn)行,則為 undefined
):
function myFunction() { console.log(this); } // 簡(jiǎn)單調(diào)用 myFunction(); // logs global object (window)
在方法調(diào)用過(guò)程中,this
的值是擁有該方法的對(duì)象:
const myObject = { method() { console.log(this); } }; // 方法調(diào)用 myObject.method(); // logs "myObject"
在使用 myFunc.call(context, arg1, ..., argN)
或 myFunc.apply(context, [arg1, ..., argN])
的間接調(diào)用中,this
的值等于第一個(gè)參數(shù):
function myFunction() { console.log(this); } const myContext = { value: 'A' }; myFunction.call(myContext); // logs { value: 'A' } myFunction.apply(myContext); // logs { value: 'A' }
在使用關(guān)鍵字 new
的構(gòu)造函數(shù)調(diào)用期間,this
等于新創(chuàng)建的實(shí)例:
function MyFunction() { console.log(this); } new MyFunction(); // logs an instance of MyFunction
1.2箭頭函數(shù)
箭頭函數(shù)中 this
的行為與常規(guī)函數(shù)的 this
行為有很大不同。
無(wú)論如何執(zhí)行或在何處執(zhí)行,箭頭函數(shù)內(nèi)部的 this
值始終等于外部函數(shù)的 this
值。換句話說(shuō),箭頭函數(shù)可按詞法解析 this
,箭頭函數(shù)沒(méi)有定義自己的執(zhí)行上下文。
在以下示例中,myMethod()
是箭頭函數(shù) callback()
的外部函數(shù):
const myObject = { myMethod(items) { console.log(this); // logs "myObject" const callback = () => { console.log(this); // logs "myObject" }; items.forEach(callback); } }; myObject.myMethod([1, 2, 3]);
箭頭函數(shù) callback()
中的 this
值等于外部函數(shù) myMethod()
的 this
。
this
詞法解析是箭頭函數(shù)的重要功能之一。在方法內(nèi)部使用回調(diào)時(shí),要確保箭頭函數(shù)沒(méi)有定義自己的 this
:不再有 const self = this
或者 callback.bind(this)
這種解決方法。
2.構(gòu)造函數(shù)
2.1 常規(guī)函數(shù)
如上一節(jié)所述,常規(guī)函數(shù)可以輕松的構(gòu)造對(duì)象。
例如用 Car()
函數(shù)創(chuàng)建汽車(chē)的實(shí)例:
function Car(color) { this.color = color; } const redCar = new Car('red'); redCar instanceof Car; // => true
Car
是常規(guī)函數(shù),使用關(guān)鍵字 new
調(diào)用時(shí)會(huì)創(chuàng)建 Car
類(lèi)型的新實(shí)例。
2.2 箭頭函數(shù)
this
詞法解決了箭頭函數(shù)不能用作構(gòu)造函數(shù)。
如果你嘗試調(diào)用帶有 new
關(guān)鍵字前綴的箭頭函數(shù),則 JavaScript 會(huì)引發(fā)錯(cuò)誤:
const Car = (color) => { this.color = color; }; const redCar = new Car('red'); // TypeError: Car is not a constructor
調(diào)用 new Car('red')
(其中 Car
是箭頭函數(shù))會(huì)拋出 TypeError: Car is not a constructor
。
3. arguments 對(duì)象
3.1 常規(guī)函數(shù)
在常規(guī)函數(shù)的主體內(nèi)部,arguments
是一個(gè)特殊的類(lèi)似于數(shù)組的對(duì)象,其中包含被調(diào)用函數(shù)的參數(shù)列表。
讓我們用 3 個(gè)參數(shù)調(diào)用 myFunction
函數(shù):
function myFunction() { console.log(arguments); } myFunction('a', 'b'); // logs { 0: 'a', 1: 'b'}
類(lèi)似于數(shù)組對(duì)象的 arguments
中包含調(diào)用參數(shù):'a'
和 'b'
。
3.2箭頭函數(shù)
另一方面,箭頭函數(shù)內(nèi)部未定義 arguments
特殊關(guān)鍵字。
用詞法解析 arguments
對(duì)象:箭頭函數(shù)從外部函數(shù)訪問(wèn) arguments
。
讓我們?cè)囍诩^函數(shù)內(nèi)部訪問(wèn) arguments
:
function myRegularFunction() { const myArrowFunction = () => { console.log(arguments); } myArrowFunction('c', 'd'); } myRegularFunction('a', 'b'); // logs { 0: 'a', 1: 'b' }
箭頭函數(shù) myArrowFunction()
由參數(shù) 'c'
, 'd'
調(diào)用。在其主體內(nèi)部,arguments
對(duì)象等于調(diào)用 myRegularFunction()
的參數(shù): 'a'
, 'b'
。
如果你想訪問(wèn)箭頭函數(shù)的直接參數(shù),可以使用剩余參數(shù) ...args
:
function myRegularFunction() { const myArrowFunction = (...args) => { console.log(args); } myArrowFunction('c', 'd'); } myRegularFunction('a', 'b'); // logs { 0: 'c', 1: 'd' }
剩余參數(shù) ... args
接受箭頭函數(shù)的執(zhí)行參數(shù):{ 0: 'c', 1: 'd' }
。
4.隱式返回
4.1常規(guī)函數(shù)
使用 return expression
語(yǔ)句從函數(shù)返回結(jié)果:
function myFunction() { return 42; } myFunction(); // => 42
如果缺少 return
語(yǔ)句,或者 return 語(yǔ)句后面沒(méi)有表達(dá)式,則常規(guī)函數(shù)隱式返回 undefined
:
function myEmptyFunction() { 42; } function myEmptyFunction2() { 42; return; } myEmptyFunction(); // => undefined myEmptyFunction2(); // => undefined
4.2箭頭函數(shù)
可以用與常規(guī)函數(shù)相同的方式從箭頭函數(shù)返回值,但有一個(gè)有用的例外。
如果箭頭函數(shù)包含一個(gè)表達(dá)式,而你省略了該函數(shù)的花括號(hào),則將顯式返回該表達(dá)式。這些是內(nèi)聯(lián)箭頭函數(shù)
const increment = (num) => num + 1; increment(41); // => 42
increment()
僅包含一個(gè)表達(dá)式:num + 1
。該表達(dá)式由箭頭函數(shù)隱式返回,而無(wú)需使用 return
關(guān)鍵字。
5. 方法
5.1 常規(guī)函數(shù)
常規(guī)函數(shù)是在類(lèi)上定義方法的常用方式。
在下面 Hero
類(lèi)中,用了常規(guī)函數(shù)定義方法 logName()
:
class Hero { constructor(heroName) { this.heroName = heroName; } logName() { console.log(this.heroName); }} const batman = new Hero('Batman');
通常把常規(guī)函數(shù)用作方法。
有時(shí)你需要把該方法作為回調(diào)提供給 setTimeout()
或事件監(jiān)聽(tīng)器。在這種情況下,你可能會(huì)很難以訪問(wèn) this
的值。
例如用 logName()
方法作為 setTimeout()
的回調(diào):
setTimeout(batman.logName, 1000); // after 1 second logs "undefined"
1 秒鐘后,undefined
會(huì)輸出到控制臺(tái)。 setTimeout()
執(zhí)行 logName
的簡(jiǎn)單調(diào)用(其中 this
是全局對(duì)象)。這時(shí)方法會(huì)與對(duì)象分離。
讓我們手動(dòng)把 this
值綁定到正確的上下文:
setTimeout(batman.logName.bind(batman), 1000); // after 1 second logs "Batman"
batman.logName.bind(batman)
將 this
值綁定到 batman
實(shí)例?,F(xiàn)在,你可以確定該方法不會(huì)丟失上下文。
手動(dòng)綁定 this
需要樣板代碼,尤其是在你有很多方法的情況下。有一種更好的方法:把箭頭函數(shù)作為類(lèi)字段。
5.2 箭頭函數(shù)
感謝類(lèi)字段提案(目前在第3階段),你可以將箭頭函數(shù)用作類(lèi)中的方法。
與常規(guī)函數(shù)相反,現(xiàn)在用箭頭定義的方法能夠把 this
詞法綁定到類(lèi)實(shí)例。
讓我們把箭頭函數(shù)作為字段:
class Hero { constructor(heroName) { this.heroName = heroName; } logName = () => { console.log(this.heroName); } } const batman = new Hero('Batman');
現(xiàn)在,你可以把 batman.logName
用于回調(diào)而無(wú)需手動(dòng)綁定 this
。 logName()
方法中 this
的值始終是類(lèi)實(shí)例:
setTimeout(batman.logName, 1000); // after 1 second logs "Batman"
6. 總結(jié)
了解常規(guī)函數(shù)和箭頭函數(shù)之間的差異有助于為特定需求選擇正確的語(yǔ)法。
常規(guī)函數(shù)中的 this
值是動(dòng)態(tài)的,并取決于調(diào)用方式。是箭頭函數(shù)中的 this
在詞法上是綁定的,等于外部函數(shù)的 this
。
常規(guī)函數(shù)中的 arguments
對(duì)象包含參數(shù)列表。相反,箭頭函數(shù)未定義 arguments
(但是你可以用剩余參數(shù) ...args
輕松訪問(wèn)箭頭函數(shù)參數(shù))。
如果箭頭函數(shù)有一個(gè)表達(dá)式,則即使不用 return
關(guān)鍵字也將隱式返回該表達(dá)式。
最后一點(diǎn),你可以在類(lèi)內(nèi)部使用箭頭函數(shù)語(yǔ)法定義去方法。粗箭頭方法將 this
值綁定到類(lèi)實(shí)例。
不管怎樣調(diào)用胖箭頭方法,this
始終等于類(lèi)實(shí)例,在回調(diào)這些方法用時(shí)非常有用。
感興趣的朋友可以使用在線HTML/CSS/JavaScript代碼運(yùn)行工具:http://tools.jb51.net/code/HtmlJsRun測(cè)試上述代碼運(yùn)行效果。
更多關(guān)于JavaScript相關(guān)內(nèi)容可查看本站專(zhuān)題:《JavaScript常用函數(shù)技巧匯總》、《javascript面向?qū)ο笕腴T(mén)教程》、《JavaScript錯(cuò)誤與調(diào)試技巧總結(jié)》、《JavaScript數(shù)據(jù)結(jié)構(gòu)與算法技巧總結(jié)》及《JavaScript數(shù)學(xué)運(yùn)算用法總結(jié)》
希望本文所述對(duì)大家JavaScript程序設(shè)計(jì)有所幫助。
- JS中箭頭函數(shù)與this的寫(xiě)法和理解
- JavaScript中的函數(shù)申明、函數(shù)表達(dá)式、箭頭函數(shù)
- JavaScript基礎(chǔ)之this和箭頭函數(shù)詳析
- JavaScript箭頭函數(shù)中的this詳解
- 深入理解JavaScript 箭頭函數(shù)
- JavaScript函數(shù)式編程(Functional Programming)箭頭函數(shù)(Arrow functions)用法分析
- JavaScript ES6箭頭函數(shù)使用指南
- 淺談箭頭函數(shù)寫(xiě)法在ReactJs中的使用
- JavaScript箭頭函數(shù)_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
- JavaScript哪些場(chǎng)景不能使用箭頭函數(shù)
相關(guān)文章
JS實(shí)現(xiàn)添加,替換,刪除節(jié)點(diǎn)元素的方法
這篇文章主要介紹了JS實(shí)現(xiàn)添加,替換,刪除節(jié)點(diǎn)元素的方法,實(shí)例分析了javascript針對(duì)節(jié)點(diǎn)元素的替換、刪除及常用的幾種添加技巧,需要的朋友可以參考下2016-06-06HTML中不支持靜態(tài)Expando的元素的問(wèn)題
HTML中不支持靜態(tài)Expando的元素的問(wèn)題...2007-03-03JavaScript數(shù)值轉(zhuǎn)換的三種方式總結(jié)
JavaScript數(shù)值轉(zhuǎn)換一般有三種方式,Number(param)函數(shù)、parseInt(param)、parseIFloat(param),下面為大家詳細(xì)介紹,需要的朋友可以參考下2014-07-07document.createElement()用法及注意事項(xiàng)(ff下不兼容)
今天處理了一個(gè)日期選擇器的ie和ff的兼容問(wèn)題,本來(lái)這種情況就很難找錯(cuò)誤,找了好久才把錯(cuò)誤定位到j(luò)s中創(chuàng)建元素的方法document.createElement(),這個(gè)方法在ie下支持這樣創(chuàng)建元素2013-03-03js實(shí)現(xiàn)按鈕控制帶有停頓效果的圖片滾動(dòng)
這篇文章主要介紹了js實(shí)現(xiàn)按鈕控制帶有停頓效果的圖片滾動(dòng),,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08JS實(shí)現(xiàn)簡(jiǎn)單隨機(jī)3D骰子
這篇文章主要為大家詳細(xì)介紹了JS實(shí)現(xiàn)簡(jiǎn)單隨機(jī)3D骰子,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10