關(guān)于箭頭函數(shù)和普通函數(shù)

前言

箭頭函數(shù)是ES6中新增的特性过蹂,因其在語言上的簡潔性,相信很多人都非常喜歡使用它。對于初學(xué)者來說殿怜,對于箭頭函數(shù)的熟練使用與深刻理解需要一個過程。本文總結(jié)一下普通函數(shù)與箭頭函數(shù)的區(qū)別曙砂,希望能夠使這一過程加速头谜。

基本語法

ES6允許使用“箭頭”(=>)定義函數(shù)。具體的定義鸠澈,可以看下面的例子柱告。

var f = v => v

// 等同于
var f = function (v) {
  return v
}

可以看出,定義箭頭函在數(shù)語法上要比普通函數(shù)簡潔得多笑陈。箭頭函數(shù)省去了function關(guān)鍵字际度,采用箭頭=>來定義函數(shù)。函數(shù)的參數(shù)放在=>前面的括號中新锈,函數(shù)體跟在=>后的花括號中甲脏。

箭頭函數(shù)的參數(shù)

1、如果箭頭函數(shù)沒有參數(shù)妹笆,直接寫一個空括號即可块请。

var f = () => 5
// 等同于
var f = function () { return 5 }

2、如果箭頭函數(shù)的參數(shù)只有一個拳缠,也可以省去包裹參數(shù)的括號墩新。

var f = v => v

// 等同于
var f = function (v) {
  return v
}

3、如果箭頭函數(shù)有多個參數(shù)窟坐,將參數(shù)依次用逗號(,)分隔海渊,包裹在括號中即可绵疲。

var sum = (num1, num2) => num1 + num2
// 等同于
var sum = function(num1, num2) {
  return num1 + num2
}

箭頭函數(shù)的函數(shù)體

1、如果箭頭函數(shù)的函數(shù)體只有一句代碼臣疑,就是簡單返回某個變量或者返回一個簡單的JS表達式盔憨,可以省去函數(shù)體的大括號{ }

var f = v => v

2讯沈、如果箭頭函數(shù)的函數(shù)體只有一句代碼郁岩,就是返回一個對象,要使用()

// 用小括號包裹要返回的對象缺狠,不報錯
let getTempItem = id => ({ id: id, name: "Temp" });

// 但絕不能這樣寫问慎,會報錯。
// 因為對象的大括號會被解釋為函數(shù)體的大括號
let getTempItem = id => { id: id, name: "Temp" };

3挤茄、如果箭頭函數(shù)的函數(shù)體只有一條語句并且不需要返回值(最常見是調(diào)用一個函數(shù))如叼,可以給這條語句前面加一個void關(guān)鍵字

let fn = () => void doesNotReturn()

箭頭函數(shù)實際使用場景

1、箭頭函數(shù)可以與變量解構(gòu)結(jié)合使用穷劈×。可以用在請求接口時,只接受的返回數(shù)據(jù)中需要的字段囚衔。

const full = ({ first, last }) => first + ' ' + last;

// 等同于
function full(person) {
  return person.first + ' ' + person.last;
}

2挖腰、箭頭函數(shù)可以簡化回調(diào)函數(shù)雕沿。

// 正常函數(shù)寫法
[1,2,3].map(function (x) {
  return x * x;
});

// 箭頭函數(shù)寫法
[1,2,3].map(x => x * x);

3练湿、rest參數(shù)與箭頭函數(shù)結(jié)合簡化開發(fā)。

const numbers = (...nums) => nums;

numbers(1, 2, 3, 4, 5)
// [1,2,3,4,5]

const headAndTail = (head, ...tail) => [head, tail];

headAndTail(1, 2, 3, 4, 5)
// [1,[2,3,4,5]]

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

箭頭函數(shù)中的this指向

1审轮、箭頭函數(shù)沒有原型prototype

let a = () =>{};
console.log(a.prototype); // undefined

2肥哎、箭頭函數(shù)不會創(chuàng)建自己的this

箭頭函數(shù)不會創(chuàng)建自己的this,所以它沒有自己的this疾渣,它只會從自己的作用域鏈的上一層繼承this篡诽。

箭頭函數(shù)沒有自己的this,它會捕獲自己在定義時(注意榴捡,是定義時杈女,不是調(diào)用時)所處的外層執(zhí)行環(huán)境的this,并繼承這個this值吊圾。所以达椰,箭頭函數(shù)中this的指向在它被定義的時候就已經(jīng)確定了,之后永遠(yuǎn)不會改變项乒。

var id = 'Global';

function fun1() {
    // setTimeout中使用普通函數(shù)
    setTimeout(function(){
        console.log(this.id);
    }, 2000);
}

function fun2() {
    // setTimeout中使用箭頭函數(shù)
    setTimeout(() => {
        console.log(this.id);
    }, 2000)
}

fun1.call({id: 'Obj'});     // 'Global'

fun2.call({id: 'Obj'});     // 'Obj'

3啰劲、不能修改箭頭函數(shù)的this指向

由于箭頭函數(shù)的this定義時就已經(jīng)確定且永遠(yuǎn)不會改變。所以使用這些方法永遠(yuǎn)也改變不了箭頭函數(shù)this的指向檀何,雖然這么做代碼不會報錯蝇裤。

var id = 'Global';
// 箭頭函數(shù)定義在全局作用域
let fun1 = () => {
    console.log(this.id)
};

fun1();     // 'Global'
// this的指向不會改變廷支,永遠(yuǎn)指向Window對象
fun1.call({id: 'Obj'});     // 'Global'
fun1.apply({id: 'Obj'});    // 'Global'
fun1.bind({id: 'Obj'})();   // 'Global'

4、箭頭函數(shù)不能作為構(gòu)造函數(shù)使用

我們先了解普通函數(shù)new構(gòu)造函數(shù)的步驟:

  • ``JS```內(nèi)部首先會先生成一個對象栓辜。
  • 再把函數(shù)中的this指向該對象恋拍。
  • 然后執(zhí)行構(gòu)造函數(shù)中的語句。
  • 最后隱式的返回this藕甩。

但是箭頭函數(shù)沒有自己的this芝囤,它的this其實是繼承了外層執(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('cao', 24)

5、箭頭函數(shù)沒有自己的arguments

箭頭函數(shù)沒有自己的arguments對象辉阶。在箭頭函數(shù)中訪問arguments實際上獲得的是外層局部(函數(shù))執(zhí)行環(huán)境中的值先壕。

除了arguments、this以下兩個變量在箭頭函數(shù)之中也是不存在的谆甜,指向外層函數(shù)的對應(yīng)變量:super垃僚、new.target。

(1) 箭頭函數(shù)的this指向全局對象规辱,會報arguments未聲明的錯誤谆棺。

let b = () => {
  console.log(arguments);
};
b(1, 2, 3, 4); // Uncaught ReferenceError: arguments is not defined

(2) 箭頭函數(shù)的this如果指向普通函數(shù),它的argumens繼承于該普通函數(shù)。

function bar() {
  console.log(arguments); // ['bar']
  bb('bb');
  function bb() {
    console.log(arguments); // ["bb"]
    let a = () => {
      console.log(arguments); // ["bb"]
    };
    a('箭頭函數(shù)的參數(shù)'); // this指向bb
  }
}
bar('bar');

可以在箭頭函數(shù)中使用rest參數(shù)代替arguments對象罕袋,來訪問箭頭函數(shù)的參數(shù)列表8氖纭!

rest參數(shù)獲取參數(shù)列表

ES6 引入 rest參數(shù)(形式為...變量名)浴讯,用于獲取函數(shù)的多余參數(shù)朵夏,這樣就不需要使用arguments對象了。rest參數(shù)搭配的變量是一個數(shù)組榆纽,該變量將多余的參數(shù)放入數(shù)組中仰猖。

let a = (a, ...bcd) => {
  console.log(a, bcd); // 1 [2, 3, 4]
};
a(1, 2, 3, 4);

上面的例子除了第一個參數(shù)確定外,用一個變量接收其他的變量奈籽。當(dāng)然你也可以使用一個變量接收所有的參數(shù)饥侵。

rest參數(shù)需要注意的點

1、rest 參數(shù)必須是最后一個參數(shù)唠摹,否則會報錯爆捞。

// 報錯
function f(a, ...b, c) {
  // ...
}

2、rest 參數(shù)沒有函數(shù)的length屬性勾拉。

(function(a) {}).length  // 1
(function(...a) {}).length  // 0
(function(a, ...b) {}).length  // 1

6煮甥、箭頭函數(shù)不支持重命名函數(shù)參數(shù),普通函數(shù)的函數(shù)參數(shù)支持重命名

function func1(a, a) {
  console.log(a, arguments); // 2 [1,2]
}

var func2 = (a,a) => {
  console.log(a); // 報錯:在此上下文中不允許重復(fù)參數(shù)名稱
};
func1(1, 2); func2(1, 2);

7盗温、語法更加簡潔、清晰

從上面的基本語法示例中可以看出成肘,箭頭函數(shù)的定義要比普通函數(shù)定義簡潔卖局、清晰得多,很快捷双霍。

箭頭函數(shù)的不適用場景

本段摘自阮一峰ES6入門了解詳情可點擊參考砚偶。

1、定義對象的方法洒闸,且該方法內(nèi)部包括this染坯。

const cat = {
  lives: 9,
  jumps: () => {
    this.lives--;
  }
}

上面代碼中,cat.jumps()方法是一個箭頭函數(shù)丘逸,這是錯誤的单鹿。調(diào)用cat.jumps()時,如果是普通函數(shù)深纲,該方法內(nèi)部的this指向cat仲锄;如果寫成上面那樣的箭頭函數(shù),使得this指向全局對象湃鹊,因此不會得到預(yù)期結(jié)果儒喊。這是因為對象不構(gòu)成單獨的作用域,導(dǎo)致jumps箭頭函數(shù)定義時的作用域就是全局作用域币呵。

2怀愧、需要動態(tài)this的時候,不應(yīng)使用箭頭函數(shù)富雅。

var button = document.getElementById('press');
button.addEventListener('click', () => {
  this.classList.toggle('on');
});

上面代碼運行時掸驱,點擊按鈕會報錯肛搬,因為button的監(jiān)聽函數(shù)是一個箭頭函數(shù)没佑,導(dǎo)致里面的this就是全局對象。如果改成普通函數(shù)温赔,this就會動態(tài)指向被點擊的按鈕對象蛤奢。

本章內(nèi)容小結(jié)

箭頭函數(shù)的使用

  1. 箭頭函數(shù)可以與變量解構(gòu)結(jié)合使用√赵簦可以用在請求接口時啤贩,只接受的返回數(shù)據(jù)中需要的字段。
  2. 箭頭函數(shù)可以簡化回調(diào)函數(shù)拜秧。
  3. 如果箭頭函數(shù)有多個參數(shù)痹屹,將參數(shù)依次用逗號(,)分隔,包裹在括號中即可枉氮。

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

  1. 箭頭函數(shù)沒有原型prototype志衍。
  2. 箭頭函數(shù)不會創(chuàng)建自己的this暖庄。
  3. 不能修改箭頭函數(shù)的this指向。
  4. 箭頭函數(shù)不能作為構(gòu)造函數(shù)使用楼肪。
  5. 箭頭函數(shù)沒有自己的arguments培廓。(super、new.target也沒有)春叫。
  6. 箭頭函數(shù)不支持重命名函數(shù)參數(shù),普通函數(shù)的函數(shù)參數(shù)支持重命名肩钠。
  7. 語法更加簡潔、清晰暂殖。

箭頭函數(shù)不適用場景

  1. 箭頭函數(shù)的this意外指向和代碼的可讀性价匠。

注意事項:

  1. 箭頭函數(shù)一條語句返回對象字面量,需要加括號呛每。
  2. 箭頭函數(shù)在參數(shù)和箭頭之間不能換行霞怀。
  3. 箭頭函數(shù)的rest參數(shù)需要放在最后。

參考文章

總結(jié)

箭頭函數(shù)是ES6重點知識了毙石,不管是在面試上,還是在平時開發(fā)中颓遏,都是經(jīng)常會被問道且使用到的知識徐矩。因此,我們應(yīng)該系統(tǒng)的去掌握和深入理解它叁幢。希望還不是很熟練的童鞋要抓緊時間學(xué)習(xí)滤灯,它值得我們大家花時間去整理和總結(jié)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末曼玩,一起剝皮案震驚了整個濱河市鳞骤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌黍判,老刑警劉巖豫尽,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異顷帖,居然都是意外死亡美旧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進店門贬墩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來榴嗅,“玉大人,你說我怎么就攤上這事陶舞∷圆猓” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵肿孵,是天一觀的道長唠粥。 經(jīng)常有香客問我优炬,道長,這世上最難降的妖魔是什么厅贪? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任蠢护,我火速辦了婚禮,結(jié)果婚禮上养涮,老公的妹妹穿的比我還像新娘葵硕。我一直安慰自己,他們只是感情好贯吓,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布懈凹。 她就那樣靜靜地躺著,像睡著了一般悄谐。 火紅的嫁衣襯著肌膚如雪介评。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天爬舰,我揣著相機與錄音们陆,去河邊找鬼。 笑死情屹,一個胖子當(dāng)著我的面吹牛坪仇,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播垃你,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼椅文,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了惜颇?” 一聲冷哼從身側(cè)響起皆刺,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凌摄,沒想到半個月后羡蛾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡望伦,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年林说,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片屯伞。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖豪直,靈堂內(nèi)的尸體忽然破棺而出劣摇,到底是詐尸還是另有隱情,我是刑警寧澤弓乙,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布末融,位于F島的核電站钧惧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏勾习。R本人自食惡果不足惜浓瞪,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望巧婶。 院中可真熱鬧乾颁,春花似錦、人聲如沸艺栈。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽湿右。三九已至诅妹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間毅人,已是汗流浹背吭狡。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留丈莺,地道東北人赵刑。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像场刑,于是被迫代替她去往敵國和親般此。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容