摘要:因?yàn)樗划a(chǎn)生屬于它自己上下文的箭頭函數(shù)的另一個(gè)用處是簡(jiǎn)化回調(diào)函數(shù)。箭頭函數(shù)使用場(chǎng)景箭頭函數(shù)適合于無(wú)復(fù)雜邏輯或者無(wú)副作用的純函數(shù)場(chǎng)景下,例如用在的回調(diào)函數(shù)定義中,另外目前等庫(kù),都大量使用箭頭函數(shù),直接定義的情況已經(jīng)很少了。
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è)玩意你要是再寫(xiě)錯(cuò)就只能說(shuō)有點(diǎn)過(guò)分了。
第二個(gè)問(wèn)題:節(jié)省大量代碼,我們先不用管下面的ES6代碼為什么這樣的語(yǔ)法能實(shí)現(xiàn)同樣的功能,我們就直觀的感受一下代碼量。
ES5寫(xiě)法:
function addFive(num){ return num+5; } alert(addFive(10));
ES6寫(xiě)法:
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)寫(xiě)的函數(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ì)寫(xiě)錯(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)的……),寫(xiě)一兩次你就習(xí)慣新的寫(xiě)法了。
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ù)寫(xiě)法 [1,2,3].map(function (x) { return x * x; }); // 箭頭函數(shù)寫(xiě)法 [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)寫(xiě)形式。這在語(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ě)新項(xiàng)目的時(shí)候,要不斷的琢磨箭頭函數(shù)使用場(chǎng)景、特點(diǎn),享受使用箭頭函數(shù)帶來(lái)的便利,這樣才能更快地成長(zhǎng)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/104201.html
摘要:正是因?yàn)樗鼪](méi)有,所以也就不能用作構(gòu)造函數(shù)。不可以當(dāng)作構(gòu)造函數(shù),也就是說(shuō),不可以使用命令,否則會(huì)拋出一個(gè)錯(cuò)誤。不可以使用對(duì)象,該對(duì)象在函數(shù)體內(nèi)不存在。 箭頭函數(shù) 在之前ES5的版本中,我們定義一個(gè)函數(shù)的形式如下: function a() { // do something…… } 但是在ES6中,則新增了箭頭函數(shù)的方式,ES6中允許使用箭頭(=>)來(lái)定義函數(shù)。 () => { ...
摘要:在這里,如果用箭頭函數(shù),可以這樣改寫(xiě)箭頭函數(shù)并沒(méi)有自己的,所以事件處理函數(shù)的調(diào)用者并不受影響。比如,在需要?jiǎng)討B(tài)上下文的場(chǎng)景中,使用箭頭函數(shù)需要格外地小心,這些場(chǎng)景包括對(duì)象的方法原型方法事件的回調(diào)構(gòu)造函數(shù)。 showImg(https://segmentfault.com/img/bVboce6?w=1304&h=734); 前言 年味兒漸散,收拾下心情,繼續(xù)敲代碼吧。 對(duì)于即將到來(lái)金三...
摘要:關(guān)于的學(xué)習(xí)總結(jié)昨天寫(xiě)了第一篇,主要是關(guān)于變量聲明關(guān)鍵字和,新增類型以及模板字符串,今天準(zhǔn)備寫(xiě)第二篇,里面的函數(shù)部分,新增了箭頭函數(shù),參數(shù)以及參數(shù)默認(rèn)值。,這次我們?cè)谡{(diào)用函數(shù)大的時(shí)候,兩個(gè)參數(shù)全部傳遞了值,因此返回。 關(guān)于ES6的學(xué)習(xí)總結(jié),昨天寫(xiě)了第一篇,主要是關(guān)于變量聲明關(guān)鍵字let和const,新增類型Symbol以及模板字符串,今天準(zhǔn)備寫(xiě)第二篇,ES6里面的函數(shù)部分,ES6新增了箭...
摘要:但是箭頭函數(shù)并沒(méi)有自己的其是繼承了外層執(zhí)行環(huán)境的,且不能改變,因此不能作為構(gòu)造函數(shù),此時(shí),引擎會(huì)在報(bào)錯(cuò)。不能作為事件的回調(diào)在中,事件的回調(diào)函數(shù)中,會(huì)動(dòng)態(tài)的指向監(jiān)聽(tīng)的對(duì)象,但是由于監(jiān)聽(tīng)是一個(gè)全局函數(shù),所以箭頭函數(shù)的回調(diào)中指向。 箭頭函數(shù) es6中添加了函數(shù)新的定義語(yǔ)法——箭頭函數(shù),當(dāng)有大于一個(gè)形參的時(shí)候,必須使用()代表部分參數(shù),函數(shù)體大于一行時(shí),必須使用{}將函數(shù)體括起來(lái),并使用ret...
摘要:注意因?yàn)榧^函數(shù)內(nèi)部的是指向外層代碼塊的最近的,例中的函數(shù)的,所以我們可以通過(guò)改變外層代碼塊的的指向從而改變箭頭函數(shù)中的指向例中使用了函數(shù)的方法。 一、this關(guān)鍵字小測(cè)試 ES6箭頭函數(shù)體中的this指向哪里? 在回答這個(gè)問(wèn)題之前先來(lái)揣揣你對(duì)this關(guān)鍵字的了解程度:(讓我們回到ES6之前)題: var obj = { a: function() { cons...
閱讀 2395·2021-09-22 16:01
閱讀 3161·2021-09-22 15:41
閱讀 1177·2021-08-30 09:48
閱讀 494·2019-08-30 15:52
閱讀 3332·2019-08-30 13:57
閱讀 1717·2019-08-30 13:55
閱讀 3663·2019-08-30 11:25
閱讀 766·2019-08-29 17:25