溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

JavaScript箭頭函數(shù)和普通函數(shù)的區(qū)別

發(fā)布時間:2020-06-12 17:22:40 來源:億速云 閱讀:211 作者:元一 欄目:web開發(fā)

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)文章!

向AI問一下細(xì)節(jié)

免責(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)容。

AI