ES6標(biāo)準(zhǔn) Arrow Function(箭頭函數(shù)=>)
ES6—箭頭函數(shù)
0.為什么會(huì)出現(xiàn)箭頭函數(shù)?
1.傳統(tǒng)的javascript函數(shù)語(yǔ)法并沒(méi)有提供任何的靈活性,每一次你需要定義一個(gè)函數(shù)時(shí),你都必須輸入function () {},這至少會(huì)出現(xiàn)兩個(gè)問(wèn)題,ES6箭頭函數(shù)都圓滿解決了它,
第一個(gè)問(wèn)題:代碼輸入快了容易輸錯(cuò)成 funciton或者functoin或者其它,但是=>這個(gè)玩意你要是再寫錯(cuò)就只能說(shuō)有點(diǎn)過(guò)分了。
第二個(gè)問(wèn)題:節(jié)省大量代碼,我們先不用管下面的ES6代碼為什么這樣的語(yǔ)法能實(shí)現(xiàn)同樣的功能,我們就直觀的感受一下代碼量。
ES5寫法:
function addFive(num){ return num+5; } alert(addFive(10));
ES6寫法:
var addFive = num=>num+5; alert(addFive(5));
沒(méi)有function、沒(méi)有return,沒(méi)有(),沒(méi)有{},這些全變成了浮云,世界好清靜。
從上面我們就可以看到,使用箭頭函數(shù)不僅僅能夠避免錯(cuò)誤,同時(shí)還能讓我們少一丟丟代碼,當(dāng)然實(shí)際工作中遠(yuǎn)比這個(gè)代碼量節(jié)省更多。
一方面是因?yàn)榉e累效應(yīng),每一部分少一丟丟合起來(lái)就多了,一方面是它還有更能節(jié)省代碼和大幅提高工作效率的場(chǎng)景。
接下來(lái)我們就說(shuō)說(shuō)今天的主角--箭頭函數(shù)。
ES6標(biāo)準(zhǔn)新增了一種新的函數(shù):Arrow Function(箭頭函數(shù)),也稱“胖箭頭函數(shù)”, 允許
使用“箭頭”(=>)定義函數(shù),是一種簡(jiǎn)寫的函數(shù)表達(dá)式。
1、箭頭函數(shù)語(yǔ)法
在ES5中我們實(shí)現(xiàn)一個(gè)求和的函數(shù):
var sum = function(x, y) { return x + y }
要使用箭頭函數(shù),可以分兩步實(shí)現(xiàn)同樣的函數(shù)功能:
首先使用=>來(lái)替代關(guān)鍵詞function
var sum = (x, y) => { return x + y }
這個(gè)特性非常好?。?!
前面我們已經(jīng)說(shuō)過(guò)用=>來(lái)替代關(guān)鍵詞function就意味著不會(huì)寫錯(cuò)function了,這真是一個(gè)絕妙的設(shè)計(jì)思想!
其次,函數(shù)體只有一條返回語(yǔ)句時(shí), 我們可以省略括號(hào){}和return關(guān)鍵詞:
var sum = (x, y) => x + y
再夸張一點(diǎn)點(diǎn),如果只有一個(gè)參數(shù)時(shí),()可省略。
這是箭頭函數(shù)最簡(jiǎn)潔的形式,常用于作用簡(jiǎn)單的處理函數(shù),比如過(guò)濾:
// ES5 var array = ['1', '2345', '567', '89']; array = array.filter(function (item) { return item.length > 2; }); // ["2345", "567"] // ES6 let array = ['1', '2345', '567', '89']; array = array.filter(item => item.length > 2); // ["2345", "567"]
箭頭函數(shù)的主要使用模式如下:
// 一個(gè)參數(shù)對(duì)應(yīng)一個(gè)表達(dá)式 param => expression;// 例如 x => x+2; // 多個(gè)參數(shù)對(duì)應(yīng)一個(gè)表達(dá)式 (param [, param]) => expression; //例如 (x,y) => (x + y); // 一個(gè)參數(shù)對(duì)應(yīng)多個(gè)表示式 param => {statements;} //例如 x = > { x++; return x;}; // 多個(gè)參數(shù)對(duì)應(yīng)多個(gè)表達(dá)式 ([param] [, param]) => {statements} // 例如 (x,y) => { x++;y++;return x*y;}; //表達(dá)式里沒(méi)有參數(shù) () => expression; //例如var flag = (() => 2)(); flag等于2 () => {statements;} //例如 var flag = (() => {return 1;})(); flag就等于1 //傳入一個(gè)表達(dá)式,返回一個(gè)對(duì)象 ([param]) => ({ key: value }); //例如 var fuc = (x) => ({key:x}) var object = fuc(1); alert(object);//{key:1}
大家不要覺(jué)得好多啊,好麻煩,其實(shí)這些根本不復(fù)雜。投入一次,受益終生。(怎么感覺(jué)我像賣保險(xiǎn)的……),寫一兩次你就習(xí)慣新的寫法了。
2、箭頭函數(shù)中的 this
箭頭函數(shù)內(nèi)的this值繼承自外圍作用域。運(yùn)行時(shí)它會(huì)首先到它的父作用域找,如果父作用域還是箭頭函數(shù),那么接著向上找,直到找到我們要的this指向。
我們先看一道經(jīng)典的關(guān)于this的面試題:
var name = 'leo'; var teacher = { name: "大彬哥", showName: function () { function showTest() { alert(this.name); } showTest(); } }; teacher.showName();//結(jié)果是 leo,而我們期待的是大彬哥,這里this指向了window,我們期待指向teacher
大家知道,ES5中的this說(shuō)好聽(tīng)了叫"靈活",說(shuō)不好聽(tīng)就是瞎搞,特別容易出問(wèn)題.而且面試還非常愛(ài)考,工作更不用說(shuō)了,經(jīng)常給我們開(kāi)發(fā)搗亂,出現(xiàn)不好調(diào)試的bug,用E箭頭函數(shù)解決這個(gè)問(wèn)題就很得心應(yīng)手了。
var name = 'leo'; var teacher = { name: "大彬哥", showName: function () { let showTest = ()=>alert(this.name); showTest(); } }; teacher.showName();
箭頭函數(shù)中的this其實(shí)是父級(jí)作用域中的this。箭頭函數(shù)引用了父級(jí)的變量詞法作用域就是一個(gè)變量的作用在定義的時(shí)候就已經(jīng)被定義好,當(dāng)在本作用域中找不到變量,就會(huì)一直向父作用域中查找,直到找到為止。
由于this在箭頭函數(shù)中已經(jīng)按照詞法作用域綁定了,所以,用call或者apply調(diào)用箭頭函數(shù)時(shí),無(wú)法對(duì)this進(jìn)行綁定,即傳入的第一個(gè)參數(shù)被忽略:
var obj = { birth: 1996, getAge: function (year) { var b = this.birth; // 1996 var fn = (y) => y - this.birth; // this.birth仍是1996 return fn.call({birth:1990}, year); } }; obj.getAge(2018); // 22 ( 2018 - 1996)
由于this已經(jīng)在詞法層面完成了綁定,通過(guò)call或apply方法調(diào)用一個(gè)函數(shù)時(shí),只是傳入了參數(shù)而已,對(duì)this并沒(méi)有什么影響 。因此,這個(gè)設(shè)計(jì)節(jié)省了開(kāi)發(fā)者思考上下文綁定的時(shí)間。
3、箭頭函數(shù)的特性
3.1 箭頭函數(shù)沒(méi)有 arguments
箭頭函數(shù)不僅沒(méi)有this,常用的arguments也沒(méi)有。如果你能獲取到arguments,那它
一定是來(lái)自父作用域的。
function foo() { return () => console.log(arguments) } foo(1, 2)(3, 4) // 1,2
上例中如果箭頭函數(shù)有arguments,就應(yīng)該輸出的是3,4而不是1,2。
箭頭函數(shù)不綁定arguments,取而代之用rest參數(shù)…解決
var foo = (...args) => { return args } console.log(foo(1,3,56,36,634,6)) // [1, 3, 56, 36, 634, 6]
箭頭函數(shù)要實(shí)現(xiàn)類似純函數(shù)的效果,必須剔除外部狀態(tài)。我們可以看出,箭頭函數(shù)除了傳入的參數(shù)之外,真的在普通函數(shù)里常見(jiàn)的this、arguments、caller是統(tǒng)統(tǒng)沒(méi)有的!
如果你在箭頭函數(shù)引用了this、arguments或者參數(shù)之外的變量,那它們一定不是箭頭函數(shù)本身包含的,而是從父級(jí)作用域繼承的。
3.2 箭頭函數(shù)中不能使用 new
let Person = (name) => { this.name = name; }; let one = new Person("galler");
運(yùn)行該程序,則出現(xiàn)TypeError: Person is not a constructor
3.3 箭頭函數(shù)可以與變量解構(gòu)結(jié)合使用。
const full = ({ first, last }) => first + ' ' + last; // 等同于 function full(person) { return person.first + ' ' + person.last; } full({first: 1, last: 5}) // '1 5'
3.4 箭頭函數(shù)沒(méi)有原型屬性
var foo = () => {}; console.log(foo.prototype) //undefined
由此可以看出箭頭函數(shù)沒(méi)有原型。
另一個(gè)錯(cuò)誤是在原型上使用箭頭函數(shù),如:
function A() { this.foo = 1 } A.prototype.bar = () => console.log(this.foo) let a = new A() a.bar() //undefined
同樣,箭頭函數(shù)中的this不是指向A,而是根據(jù)變量查找規(guī)則回溯到了全局作用域。同樣,使用普通函數(shù)就不存在問(wèn)題。箭頭函數(shù)中不可加new,也就是說(shuō)箭頭函數(shù)不能當(dāng)構(gòu)造函數(shù)進(jìn)行使用。
3.5 箭頭函數(shù)不能換行
var func = () => 1; // SyntaxError: expected expression, got '=>'
如果開(kāi)發(fā)中確實(shí)一行搞不定,邏輯很多,就加{},你就想怎么換行怎么換行了。
var func = ()=>{ return '來(lái)??!互相傷害??!'; // 1.加{} 2.加return }
4、箭頭函數(shù)使用場(chǎng)景
JavaScript中this的故事已經(jīng)是非常古老了,每一個(gè)函數(shù)都有自己的上下文。
以下例子的目的是使用jQuery來(lái)展示一個(gè)每秒都會(huì)更新的時(shí)鐘:
$('.time').each(function () { setInterval(function () { $(this).text(Date.now()); }, 1000); });
當(dāng)嘗試在setInterval的回調(diào)中使用this來(lái)引用DOM元素時(shí),很不幸,我們得到的只是一個(gè)屬于回調(diào)函數(shù)自身
上下文的this。一個(gè)通常的解決辦法是定義一個(gè)that或者self變量:
$('.time').each(function () { var self = this; setInterval(function () { $(self).text(Date.now()); }, 1000); });
但當(dāng)使用箭頭函數(shù)時(shí),這個(gè)問(wèn)題就不復(fù)存在了。因?yàn)樗划a(chǎn)生屬于它自己上下文的this:
$('.time').each(function () { setInterval(() => $(this).text(Date.now()), 1000); });
箭頭函數(shù)的另一個(gè)用處是簡(jiǎn)化回調(diào)函數(shù)。
// 正常函數(shù)寫法 [1,2,3].map(function (x) { return x * x; }); // 箭頭函數(shù)寫法 [1,2,3].map(x => x * x);
當(dāng)然也可以在事件監(jiān)聽(tīng)函數(shù)里使用:
document.body.addEventListener('click', event=>console.log(event, this));
// EventObject, BodyElement
5、總結(jié)
5.1 箭頭函數(shù)優(yōu)點(diǎn)
箭頭函數(shù)是使用=>語(yǔ)法的函數(shù)簡(jiǎn)寫形式。這在語(yǔ)法上與 C#、Java 8 、Python( lambda 函數(shù))和 CoffeeScript 的
相關(guān)特性非常相似。
非常簡(jiǎn)潔的語(yǔ)法,使用箭頭函數(shù)比普通函數(shù)少些動(dòng)詞,如:function或return。
() => { ... } // 零個(gè)參數(shù)用 () 表示。
x => { ... } // 一個(gè)參數(shù)可以省略 ()。
(x, y) => { ... } // 多參數(shù)不能省略 ()。
如果只有一個(gè)return,{}可以省略。
更直觀的作用域和 this的綁定,它能讓我們能很好的處理this的指向問(wèn)題。箭頭函數(shù)加上let關(guān)鍵字的使用,將會(huì)讓我們javascript代碼上一個(gè)層次。
5.2 箭頭函數(shù)使用場(chǎng)景
箭頭函數(shù)適合于無(wú)復(fù)雜邏輯或者無(wú)副作用的純函數(shù)場(chǎng)景下,例如用在map、reduce、filter的回調(diào)函數(shù)定義
中,另外目前vue、react、node等庫(kù),都大量使用箭頭函數(shù),直接定義function的情況已經(jīng)很少了。
各位同學(xué)在寫新項(xiàng)目的時(shí)候,要不斷的琢磨箭頭函數(shù)使用場(chǎng)景、特點(diǎn),享受使用箭頭函數(shù)帶來(lái)的便利,這樣才能更快地成長(zhǎng)。
下面是廖雪峰網(wǎng)站的補(bǔ)充
ES6標(biāo)準(zhǔn)新增了一種新的函數(shù):Arrow Function(箭頭函數(shù))。
為什么叫Arrow Function?因?yàn)樗亩x用的就是一個(gè)箭頭:
x => x * x
上面的箭頭函數(shù)相當(dāng)于:
function (x) {
return x * x;
}
在繼續(xù)學(xué)習(xí)箭頭函數(shù)之前,請(qǐng)測(cè)試你的瀏覽器是否支持ES6的Arrow Function:
[Ctrl+A 全選 注:引入外部Js需再刷新一下頁(yè)面才能執(zhí)行]
箭頭函數(shù)相當(dāng)于匿名函數(shù),并且簡(jiǎn)化了函數(shù)定義。箭頭函數(shù)有兩種格式,一種像上面的,只包含一個(gè)表達(dá)式,連{ ... }和return都省略掉了。還有一種可以包含多條語(yǔ)句,這時(shí)候就不能省略{ ... }和return:
x => { if (x > 0) { return x * x; } else { return - x * x; } }
如果參數(shù)不是一個(gè),就需要用括號(hào)()括起來(lái):
// 兩個(gè)參數(shù): (x, y) => x * x + y * y // 無(wú)參數(shù): () => 3.14 // 可變參數(shù): (x, y, ...rest) => { var i, sum = x + y; for (i=0; i<rest.length; i++) { sum += rest[i]; } return sum; }
如果要返回一個(gè)對(duì)象,就要注意,如果是單表達(dá)式,這么寫的話會(huì)報(bào)錯(cuò):
// SyntaxError:
x => { foo: x }
因?yàn)楹秃瘮?shù)體的{ ... }有語(yǔ)法沖突,所以要改為:
// ok:
x => ({ foo: x })
this
箭頭函數(shù)看上去是匿名函數(shù)的一種簡(jiǎn)寫,但實(shí)際上,箭頭函數(shù)和匿名函數(shù)有個(gè)明顯的區(qū)別:箭頭函數(shù)內(nèi)部的this是詞法作用域,由上下文確定。
回顧前面的例子,由于JavaScript函數(shù)對(duì)this綁定的錯(cuò)誤處理,下面的例子無(wú)法得到預(yù)期結(jié)果:
var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = function () { return new Date().getFullYear() - this.birth; // this指向window或undefined }; return fn(); } };
現(xiàn)在,箭頭函數(shù)完全修復(fù)了this的指向,this總是指向詞法作用域,也就是外層調(diào)用者obj:
var obj = { birth: 1990, getAge: function () { var b = this.birth; // 1990 var fn = () => new Date().getFullYear() - this.birth; // this指向obj對(duì)象 return fn(); } }; obj.getAge(); // 25
如果使用箭頭函數(shù),以前的那種hack寫法:
var that = this;
就不再需要了。
由于this在箭頭函數(shù)中已經(jīng)按照詞法作用域綁定了,所以,用call()或者apply()調(diào)用箭頭函數(shù)時(shí),無(wú)法對(duì)this進(jìn)行綁定,即傳入的第一個(gè)參數(shù)被忽略:
var obj = { birth: 1990, getAge: function (year) { var b = this.birth; // 1990 var fn = (y) => y - this.birth; // this.birth仍是1990 return fn.call({birth:2000}, year); } }; obj.getAge(2015); // 25
練習(xí)
請(qǐng)使用箭頭函數(shù)簡(jiǎn)化排序時(shí)傳入的函數(shù):
<script> 'use strict' var arr = [10, 20, 1, 2]; arr.sort((x, y) => { if (x < y) return -1 else if (x > y) return 1 else return 0 }); console.log(arr); // [1, 2, 10, 20] </script>
以上就是ES6標(biāo)準(zhǔn) Arrow Function(箭頭函數(shù)=>)的詳細(xì)內(nèi)容,更多關(guān)于js 箭頭函數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- ES6中箭頭函數(shù)的定義與調(diào)用方式詳解
- javascript ES6中箭頭函數(shù)注意細(xì)節(jié)小結(jié)
- ES6中的箭頭函數(shù)實(shí)例詳解
- 關(guān)于ES6箭頭函數(shù)中的this問(wèn)題
- 詳解Javascript ES6中的箭頭函數(shù)(Arrow Functions)
- 深入淺出ES6新特性之函數(shù)默認(rèn)參數(shù)和箭頭函數(shù)
- JavaScript ES6箭頭函數(shù)使用指南
- es6函數(shù)之箭頭函數(shù)用法實(shí)例詳解
- ES6新特性之函數(shù)的擴(kuò)展實(shí)例詳解
- ES6擴(kuò)展運(yùn)算符和rest運(yùn)算符用法實(shí)例分析
- es6數(shù)組之?dāng)U展運(yùn)算符操作實(shí)例分析
- ES6箭頭函數(shù)和擴(kuò)展實(shí)例分析
相關(guān)文章
使用JS動(dòng)態(tài)構(gòu)建目錄樹(shù)
本文詳細(xì)講解了使用JS動(dòng)態(tài)構(gòu)建目錄樹(shù)的方法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-01-01javascript模擬post提交隱藏地址欄的參數(shù)
想要隱藏地址欄的參數(shù),就只能用javascript模擬post提交,下面是示例代碼,需要的朋友可以看看2014-09-09分析javascript中9 個(gè)常見(jiàn)錯(cuò)誤阻礙你進(jìn)步
這篇文章主要介紹了分析javascript中9 個(gè)常見(jiàn)錯(cuò)誤阻礙你進(jìn)步的相關(guān)資料,希望通過(guò)本文能幫助到大家,需要的朋友可以參考下2017-09-09js實(shí)現(xiàn)隨屏幕滾動(dòng)的帶緩沖效果的右下角廣告代碼
這篇文章主要介紹了js實(shí)現(xiàn)隨屏幕滾動(dòng)的帶緩沖效果的右下角廣告代碼,涉及javascript基于數(shù)學(xué)運(yùn)算及定時(shí)函數(shù)動(dòng)態(tài)操作頁(yè)面元素的實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-09-09淺談JavaScript構(gòu)造樹(shù)形結(jié)構(gòu)的一種高效算法
這篇文章主要介紹了JavaScript構(gòu)造樹(shù)形結(jié)構(gòu)的一種高效算法,對(duì)算法感興趣的同學(xué),可以參考下2021-05-05