您好,登錄后才能下訂單哦!
JavaScript 箭頭函數(shù)大致相當(dāng)于 python 中的 lambda 函數(shù) 或 Ruby 中的 blocks。這些是匿名函數(shù),它們有自己的特殊語法,接受一定數(shù)量的參數(shù),并在其封閉的作用域的上下文(即定義它們的函數(shù)或其他代碼)中操作。這是我們在日常開發(fā)中一直使用的API,但大多數(shù)同學(xué)對它的理解還不夠,下面我們來詳細(xì)了解下箭頭函數(shù)的基本語法,以及箭頭函數(shù)與普通函數(shù)的區(qū)別。
一、基本語法
為什么會出現(xiàn)箭頭函數(shù)?
傳統(tǒng)的javascript函數(shù)語法并沒有提供任何的靈活性,每一次你需要定義一個函數(shù)時,你都必須輸入function () {},這至少會出現(xiàn)兩個問題,ES6箭頭函數(shù)都圓滿解決了它。
【1.1】定義函數(shù)
定義箭頭函在數(shù)語法上要比普通函數(shù)簡潔得多,ES6中允許使用箭頭
=>
來定義箭頭函數(shù),箭頭函數(shù)省去了 function 關(guān)鍵字,函數(shù)的參數(shù)放在=>前面的括號中,函數(shù)體跟在=>后的花括號中。
// 箭頭函數(shù) let fun = (name) => { return `Hello ${name} !`; }; // 普通函數(shù) let fun = function (name) { return `Hello ${name} !`; };
【1.2】箭頭函數(shù)的參數(shù)
① 如果箭頭函數(shù)沒有參數(shù),直接寫一個空括號即可。
② 如果箭頭函數(shù)的參數(shù)只有一個,也可以省去包裹參數(shù)的括號。
③ 如果箭頭函數(shù)有多個參數(shù),將參數(shù)依次用逗號(,)分隔,包裹在括號中即可。
// 沒有參數(shù) let fun1 = () => { console.log('dingFY'); }; // 只有一個參數(shù),可以省去參數(shù)括號 let fun2 = name => { console.log(`Hello ${name} !`) }; // 有多個參數(shù),逗號分隔 let fun3 = (val1, val2, val3) => { return [val1, val2, val3]; };
【1.3】箭頭函數(shù)的函數(shù)體
① 如果箭頭函數(shù)的函數(shù)體只有一句代碼,就是簡單返回某個變量或者返回一個簡單的JS表達(dá)式,可以省去函數(shù)體的大括號{ }。
let fun = val => val; // 等同于 let fun = function (val) { return val }; let sum = (num1, num2) => num1 + num2; // 等同于 let sum = function(num1, num2) { return num1 + num2; };
② 如果箭頭函數(shù)的函數(shù)體只有一句代碼,就是返回一個對象,可以像下面這樣寫:
// 用小括號包裹要返回的對象,不報錯 let getTempItem = id => ({ id: id, name: "Temp" }); // 但絕不能這樣寫,會報錯,因?yàn)閷ο蟮拇罄ㄌ枙唤忉尀楹瘮?shù)體的大括號 let getTempItem = id => { id: id, name: "Temp" };
③ 如果箭頭函數(shù)的函數(shù)體只有一條語句并且不需要返回值(最常見是調(diào)用一個函數(shù)),可以給這條語句前面加一個void關(guān)鍵字
let fun = () => void doesNotReturn();
二、箭頭函數(shù)與普通函數(shù)的區(qū)別
【2.1】語法更加簡潔、清晰
從上面的箭頭函數(shù)基本語法示例中可以看出,箭頭函數(shù)的定義要比普通函數(shù)定義簡潔、清晰得多,很快捷。
【2.2】箭頭函數(shù)沒有 prototype (原型),所以箭頭函數(shù)本身沒有this
// 箭頭函數(shù) let a = () => {}; console.log(a.prototype); // undefined // 普通函數(shù) function a() {}; console.log(a.prototype); // {constructor:f}
【2.3】箭頭函數(shù)不會創(chuàng)建自己的this
箭頭函數(shù)沒有自己的this,箭頭函數(shù)的this指向在定義(注意:是定義時,不是調(diào)用時)的時候繼承自外層第一個普通函數(shù)的this。所以,箭頭函數(shù)中 this 的指向在它被定義的時候就已經(jīng)確定了,之后永遠(yuǎn)不會改變。
let obj = { a: 10, b: () => { console.log(this.a); // undefined console.log(this); // Window {postMessage: ?, blur: ?, focus: ?, close: ?, frames: Window, …} }, c: function() { console.log(this.a); // 10 console.log(this); // {a: 10, b: ?, c: ?} } } obj.b(); obj.c();
【2.4】call | apply | bind 無法改變箭頭函數(shù)中this的指向
call | apply | bind方法可以用來動態(tài)修改函數(shù)執(zhí)行時this的指向,但由于箭頭函數(shù)的this定義時就已經(jīng)確定且永遠(yuǎn)不會改變。所以使用這些方法永遠(yuǎn)也改變不了箭頭函數(shù)this的指向。
var id = 10; let fun = () => { console.log(this.id) }; fun(); // 10 fun.call({ id: 20 }); // 10 fun.apply({ id: 20 }); // 10 fun.bind({ id: 20 })(); // 10
【2.4】call | apply | bind 無法改變箭頭函數(shù)中this的指向
call | apply | bind方法可以用來動態(tài)修改函數(shù)執(zhí)行時this的指向,但由于箭頭函數(shù)的this定義時就已經(jīng)確定且永遠(yuǎn)不會改變。所以使用這些方法永遠(yuǎn)也改變不了箭頭函數(shù)this的指向。
var id = 10; let fun = () => { console.log(this.id) }; fun(); // 10 fun.call({ id: 20 }); // 10 fun.apply({ id: 20 }); // 10 fun.bind({ id: 20 })(); // 10
【2.5】箭頭函數(shù)不能作為構(gòu)造函數(shù)使用
我們先了解一下構(gòu)造函數(shù)的new都做了些什么?簡單來說,分為四步: ① JS內(nèi)部首先會先生成一個對象; ② 再把函數(shù)中的this指向該對象; ③ 然后執(zhí)行構(gòu)造函數(shù)中的語句; ④ 最終返回該對象實(shí)例。
但是?。∫?yàn)榧^函數(shù)沒有自己的this,它的this其實(shí)是繼承了外層執(zhí)行環(huán)境中的this,且this指向永遠(yuǎn)不會隨在哪里調(diào)用、被誰調(diào)用而改變,所以箭頭函數(shù)不能作為構(gòu)造函數(shù)使用,或者說構(gòu)造函數(shù)不能定義成箭頭函數(shù),否則用new調(diào)用時會報錯!
let Fun = (name, age) => { this.name = name; this.age = age; }; // 報錯 let p = new Fun('dingFY', 24);
【2.6】箭頭函數(shù)不綁定arguments,取而代之用rest參數(shù)...代替arguments對象,來訪問箭頭函數(shù)的參數(shù)列表
箭頭函數(shù)沒有自己的arguments對象。在箭頭函數(shù)中訪問arguments實(shí)際上獲得的是外層局部(函數(shù))執(zhí)行環(huán)境中的值。
// 普通函數(shù) function A(a){ console.log(arguments); } A(1,2,3,4,5,8); // [1, 2, 3, 4, 5, 8, callee: ?, Symbol(Symbol.iterator): ?] // 箭頭函數(shù) let B = (b)=>{ console.log(arguments); } B(2,92,32,32); // Uncaught ReferenceError: arguments is not defined // rest參數(shù)... let C = (...c) => { console.log(c); } C(3,82,32,11323); // [3, 82, 32, 11323]
【2.7】箭頭函數(shù)不能用作Generator函數(shù),不能使用yield關(guān)鍵字
以上就是箭頭函數(shù)和普通函數(shù)區(qū)別的詳細(xì)內(nèi)容,更多請關(guān)注億速云其它相關(guān)文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。