成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

ES6 系列之箭頭函數(shù)

hsluoyz / 1826人閱讀

摘要:回顧我們先來(lái)回顧下箭頭函數(shù)的基本語(yǔ)法。主要區(qū)別包括沒(méi)有箭頭函數(shù)沒(méi)有,所以需要通過(guò)查找作用域鏈來(lái)確定的值。箭頭函數(shù)并沒(méi)有方法,不能被用作構(gòu)造函數(shù),如果通過(guò)的方式調(diào)用,會(huì)報(bào)錯(cuò)。

回顧

我們先來(lái)回顧下箭頭函數(shù)的基本語(yǔ)法。

ES6 增加了箭頭函數(shù):

let func = value => value;

相當(dāng)于:

let func = function (value) {
    return value;
};

如果需要給函數(shù)傳入多個(gè)參數(shù):

let func = (value, num) => value * num;

如果函數(shù)的代碼塊需要多條語(yǔ)句:

let func = (value, num) => {
    return value * num
};

如果需要直接返回一個(gè)對(duì)象:

let func = (value, num) => ({total: value * num});

與變量解構(gòu)結(jié)合:

let func = ({value, num}) => ({total: value * num})

// 使用
var result = func({
    value: 10,
    num: 10
})

console.log(result); // {total: 100}

很多時(shí)候,你可能想不到要這樣用,所以再來(lái)舉個(gè)例子,比如在 React 與 Immutable 的技術(shù)選型中,我們處理一個(gè)事件會(huì)這樣做:

handleEvent = () => {
  this.setState({
    data: this.state.data.set("key", "value")
  })
};

其實(shí)就可以簡(jiǎn)化為:

handleEvent = () => {
  this.setState(({data}) => ({
    data: data.set("key", "value")
  }))
};
比較

本篇我們重點(diǎn)比較一下箭頭函數(shù)與普通函數(shù)。

主要區(qū)別包括:

1.沒(méi)有 this

箭頭函數(shù)沒(méi)有 this,所以需要通過(guò)查找作用域鏈來(lái)確定 this 的值。

這就意味著如果箭頭函數(shù)被非箭頭函數(shù)包含,this 綁定的就是最近一層非箭頭函數(shù)的 this。

模擬一個(gè)實(shí)際開(kāi)發(fā)中的例子:

我們的需求是點(diǎn)擊一個(gè)按鈕,改變?cè)摪粹o的背景色。

為了方便開(kāi)發(fā),我們抽離一個(gè) Button 組件,當(dāng)需要使用的時(shí)候,直接:

// 傳入元素 id 值即可綁定該元素點(diǎn)擊時(shí)改變背景色的事件
new Button("button")

HTML 代碼如下:

JavaScript 代碼如下:

function Button(id) {
    this.element = document.querySelector("#" + id);
    this.bindEvent();
}

Button.prototype.bindEvent = function() {
    this.element.addEventListener("click", this.setBgColor, false);
};

Button.prototype.setBgColor = function() {
    this.element.style.backgroundColor = "#1abc9c"
};

var button = new Button("button");

看著好像沒(méi)有問(wèn)題,結(jié)果卻是報(bào)錯(cuò) Uncaught TypeError: Cannot read property "style" of undefined

這是因?yàn)楫?dāng)使用 addEventListener() 為一個(gè)元素注冊(cè)事件的時(shí)候,事件函數(shù)里的 this 值是該元素的引用。

所以如果我們?cè)?setBgColor 中 console.log(this),this 指向的是按鈕元素,那 this.element 就是 undefined,報(bào)錯(cuò)自然就理所當(dāng)然了。

也許你會(huì)問(wèn),既然 this 都指向了按鈕元素,那我們直接修改 setBgColor 函數(shù)為:

Button.prototype.setBgColor = function() {
    this.style.backgroundColor = "#1abc9c"
};

不就可以解決這個(gè)問(wèn)題了?

確實(shí)可以這樣做,但是在實(shí)際的開(kāi)發(fā)中,我們可能會(huì)在 setBgColor 中還調(diào)用其他的函數(shù),比如寫(xiě)成這種:

Button.prototype.setBgColor = function() {
    this.setElementColor();
    this.setOtherElementColor();
};

所以我們還是希望 setBgColor 中的 this 是指向?qū)嵗龑?duì)象的,這樣就可以調(diào)用其他的函數(shù)。

利用 ES5,我們一般會(huì)這樣做:

Button.prototype.bindEvent = function() {
    this.element.addEventListener("click", this.setBgColor.bind(this), false);
};

為避免 addEventListener 的影響,使用 bind 強(qiáng)制綁定 setBgColor() 的 this 為實(shí)例對(duì)象

使用 ES6,我們可以更好的解決這個(gè)問(wèn)題:

Button.prototype.bindEvent = function() {
    this.element.addEventListener("click", event => this.setBgColor(event), false);
};

由于箭頭函數(shù)沒(méi)有 this,所以會(huì)向外層查找 this 的值,即 bindEvent 中的 this,此時(shí) this 指向?qū)嵗龑?duì)象,所以可以正確的調(diào)用 this.setBgColor 方法, 而 this.setBgColor 中的 this 也會(huì)正確指向?qū)嵗龑?duì)象。

在這里再額外提一點(diǎn),就是注意 bindEvent 和 setBgColor 在這里使用的是普通函數(shù)的形式,而非箭頭函數(shù),如果我們改成箭頭函數(shù),會(huì)導(dǎo)致函數(shù)里的 this 指向 window 對(duì)象 (非嚴(yán)格模式下)。

最后,因?yàn)榧^函數(shù)沒(méi)有 this,所以也不能用 call()、apply()、bind() 這些方法改變 this 的指向,可以看一個(gè)例子:

var value = 1;
var result = (() => this.value).bind({value: 2})();
console.log(result); // 1
2. 沒(méi)有 arguments

箭頭函數(shù)沒(méi)有自己的 arguments 對(duì)象,這不一定是件壞事,因?yàn)榧^函數(shù)可以訪問(wèn)外圍函數(shù)的 arguments 對(duì)象:

function constant() {
    return () => arguments[0]
}

var result = constant(1);
console.log(result()); // 1

那如果我們就是要訪問(wèn)箭頭函數(shù)的參數(shù)呢?

你可以通過(guò)命名參數(shù)或者 rest 參數(shù)的形式訪問(wèn)參數(shù):

let nums = (...nums) => nums;
3. 不能通過(guò) new 關(guān)鍵字調(diào)用

JavaScript 函數(shù)有兩個(gè)內(nèi)部方法:[[Call]] 和 [[Construct]]。

當(dāng)通過(guò) new 調(diào)用函數(shù)時(shí),執(zhí)行 [[Construct]] 方法,創(chuàng)建一個(gè)實(shí)例對(duì)象,然后再執(zhí)行函數(shù)體,將 this 綁定到實(shí)例上。

當(dāng)直接調(diào)用的時(shí)候,執(zhí)行 [[Call]] 方法,直接執(zhí)行函數(shù)體。

箭頭函數(shù)并沒(méi)有 [[Construct]] 方法,不能被用作構(gòu)造函數(shù),如果通過(guò) new 的方式調(diào)用,會(huì)報(bào)錯(cuò)。

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor
4. 沒(méi)有 new.target

因?yàn)椴荒苁褂?new 調(diào)用,所以也沒(méi)有 new.target 值。

關(guān)于 new.target,可以參考 http://es6.ruanyifeng.com/#docs/class#new-target-%E5%B1%9E%E6%80%A7

5. 沒(méi)有原型

由于不能使用 new 調(diào)用箭頭函數(shù),所以也沒(méi)有構(gòu)建原型的需求,于是箭頭函數(shù)也不存在 prototype 這個(gè)屬性。

var Foo = () => {};
console.log(Foo.prototype); // undefined
6. 沒(méi)有 super

連原型都沒(méi)有,自然也不能通過(guò) super 來(lái)訪問(wèn)原型的屬性,所以箭頭函數(shù)也是沒(méi)有 super 的,不過(guò)跟 this、arguments、new.target 一樣,這些值由外圍最近一層非箭頭函數(shù)決定。

總結(jié)

最后,關(guān)于箭頭函數(shù),引用 MDN 的介紹就是:

An arrow function expression has a shorter syntax than a function expression and does not have its own this, arguments, super, or new.target. These function expressions are best suited for non-method functions, and they cannot be used as constructors.

翻譯過(guò)來(lái)就是:

箭頭函數(shù)表達(dá)式的語(yǔ)法比函數(shù)表達(dá)式更短,并且不綁定自己的this,arguments,super或 new.target。這些函數(shù)表達(dá)式最適合用于非方法函數(shù)(non-method functions),并且它們不能用作構(gòu)造函數(shù)。

那么什么是 non-method functions 呢?

我們先來(lái)看看 method 的定義:

A method is a function which is a property of an object.

對(duì)象屬性中的函數(shù)就被稱(chēng)之為 method,那么 non-mehtod 就是指不被用作對(duì)象屬性中的函數(shù)了,可是為什么說(shuō)箭頭函數(shù)更適合 non-method 呢?

讓我們來(lái)看一個(gè)例子就明白了:

var obj = {
  i: 10,
  b: () => console.log(this.i, this),
  c: function() {
    console.log( this.i, this)
  }
}
obj.b();
// undefined Window
obj.c();
// 10, Object {...}
自執(zhí)行函數(shù)

自執(zhí)行函數(shù)的形式為:

(function(){
    console.log(1)
})()

或者

(function(){
    console.log(1)
}())

利用箭頭簡(jiǎn)化自執(zhí)行函數(shù)的寫(xiě)法:

(() => {
    console.log(1)
})()

但是注意:使用以下這種寫(xiě)法卻會(huì)報(bào)錯(cuò):

(() => {
    console.log(1)
}())

為什么會(huì)報(bào)錯(cuò)呢?嘿嘿,如果你知道,可以告訴我~

ES6 系列

ES6 系列目錄地址:https://github.com/mqyqingfeng/Blog

ES6 系列預(yù)計(jì)寫(xiě)二十篇左右,旨在加深 ES6 部分知識(shí)點(diǎn)的理解,重點(diǎn)講解塊級(jí)作用域、標(biāo)簽?zāi)0?、箭頭函數(shù)、Symbol、Set、Map 以及 Promise 的模擬實(shí)現(xiàn)、模塊加載方案、異步處理等內(nèi)容。

如果有錯(cuò)誤或者不嚴(yán)謹(jǐn)?shù)牡胤?,?qǐng)務(wù)必給予指正,十分感謝。如果喜歡或者有所啟發(fā),歡迎 star,對(duì)作者也是一種鼓勵(lì)。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/107949.html

相關(guān)文章

  • ES6入門(mén)函數(shù)的擴(kuò)展

    摘要:如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時(shí),調(diào)用幀只有一項(xiàng),這將大大節(jié)省內(nèi)存。等同于等同于注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會(huì)取代外層函數(shù)的調(diào)用幀,否則就無(wú)法進(jìn)行尾調(diào)用優(yōu)化。 showImg(https://segmentfault.com/img/bVbrTHp?w=1080&h=1920); 1. 函數(shù)參數(shù)的默認(rèn)值 1.1 用法 在ES6之前是不能為...

    dackel 評(píng)論0 收藏0
  • ES6入門(mén)函數(shù)的擴(kuò)展

    摘要:如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時(shí),調(diào)用幀只有一項(xiàng),這將大大節(jié)省內(nèi)存。等同于等同于注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會(huì)取代外層函數(shù)的調(diào)用幀,否則就無(wú)法進(jìn)行尾調(diào)用優(yōu)化。 showImg(https://segmentfault.com/img/bVbrTHp?w=1080&h=1920); 1. 函數(shù)參數(shù)的默認(rèn)值 1.1 用法 在ES6之前是不能為...

    graf 評(píng)論0 收藏0
  • 箭頭函數(shù)你想知道的都在這里

    摘要:沒(méi)有箭頭函數(shù)沒(méi)有自己的對(duì)象,這不一定是件壞事,因?yàn)榧^函數(shù)可以訪問(wèn)外圍函數(shù)的對(duì)象那如果我們就是要訪問(wèn)箭頭函數(shù)的參數(shù)呢你可以通過(guò)命名參數(shù)或者參數(shù)的形式訪問(wèn)參數(shù)不能通過(guò)關(guān)鍵字調(diào)用函數(shù)有兩個(gè)內(nèi)部方法和。 1、基本語(yǔ)法回顧 我們先來(lái)回顧下箭頭函數(shù)的基本語(yǔ)法。ES6 增加了箭頭函數(shù): var f = v => v; // 等同于 var f = function (v) { return ...

    xiaoqibTn 評(píng)論0 收藏0
  • 深入理解JavaScript

    摘要:深入之繼承的多種方式和優(yōu)缺點(diǎn)深入系列第十五篇,講解各種繼承方式和優(yōu)缺點(diǎn)。對(duì)于解釋型語(yǔ)言例如來(lái)說(shuō),通過(guò)詞法分析語(yǔ)法分析語(yǔ)法樹(shù),就可以開(kāi)始解釋執(zhí)行了。 JavaScript深入之繼承的多種方式和優(yōu)缺點(diǎn) JavaScript深入系列第十五篇,講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 寫(xiě)在前面 本文講解JavaScript各種繼承方式和優(yōu)缺點(diǎn)。 但是注意: 這篇文章更像是筆記,哎,再讓我...

    myeveryheart 評(píng)論0 收藏0
  • es6基礎(chǔ)0x024:babel簡(jiǎn)單使用

    摘要:簡(jiǎn)單的說(shuō)就是,新語(yǔ)法編譯器舊語(yǔ)法。說(shuō)明所以,對(duì)于新特性,我們可以通過(guò)使用,也可以通過(guò)語(yǔ)法轉(zhuǎn)化來(lái)達(dá)到兼容。 0x001 polyfill 我們都知道,js總是一直存在著兼容性問(wèn)題,雖然其他語(yǔ)言也存在著兼容性問(wèn)題,比如c++、java,但那種兼容性是新特性在舊版本上的不兼容,js則存在著各種奇形怪哉的不兼容。這其中有著非常復(fù)雜的歷史和時(shí)代的原因,并不加以累述。而解決兼容性問(wèn)題的方法在以前只...

    wangbinke 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<