国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

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

hsluoyz / 1820人閱讀

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

回顧

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

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

let func = value => value;

相當(dāng)于:

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

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

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

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

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

如果需要直接返回一個對象:

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í)候,你可能想不到要這樣用,所以再來舉個例子,比如在 React 與 Immutable 的技術(shù)選型中,我們處理一個事件會這樣做:

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

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

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

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

主要區(qū)別包括:

1.沒有 this

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

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

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

我們的需求是點(diǎn)擊一個按鈕,改變該按鈕的背景色。

為了方便開發(fā),我們抽離一個 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");

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

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

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

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

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

不就可以解決這個問題了?

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

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

所以我們還是希望 setBgColor 中的 this 是指向?qū)嵗龑ο蟮模@樣就可以調(diào)用其他的函數(shù)。

利用 ES5,我們一般會這樣做:

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

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

使用 ES6,我們可以更好的解決這個問題:

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

由于箭頭函數(shù)沒有 this,所以會向外層查找 this 的值,即 bindEvent 中的 this,此時(shí) this 指向?qū)嵗龑ο螅钥梢哉_的調(diào)用 this.setBgColor 方法, 而 this.setBgColor 中的 this 也會正確指向?qū)嵗龑ο蟆?/p>

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

5. 沒有原型

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

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

連原型都沒有,自然也不能通過 super 來訪問原型的屬性,所以箭頭函數(shù)也是沒有 super 的,不過跟 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.

翻譯過來就是:

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

那么什么是 non-method functions 呢?

我們先來看看 method 的定義:

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

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

讓我們來看一個例子就明白了:

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)
}())

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

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

但是注意:使用以下這種寫法卻會報(bào)錯:

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

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

ES6 系列

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

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

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

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

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/107949.html

相關(guān)文章

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

    摘要:如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時(shí),調(diào)用幀只有一項(xiàng),這將大大節(jié)省內(nèi)存。等同于等同于注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會取代外層函數(shù)的調(diào)用幀,否則就無法進(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 評論0 收藏0
  • ES6入門函數(shù)的擴(kuò)展

    摘要:如果所有函數(shù)都是尾調(diào)用,那么完全可以做到每次執(zhí)行時(shí),調(diào)用幀只有一項(xiàng),這將大大節(jié)省內(nèi)存。等同于等同于注意,只有不再用到外層函數(shù)的內(nèi)部變量,內(nèi)層函數(shù)的調(diào)用幀才會取代外層函數(shù)的調(diào)用幀,否則就無法進(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 評論0 收藏0
  • 箭頭函數(shù)你想知道的都在這里

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

    xiaoqibTn 評論0 收藏0
  • 深入理解JavaScript

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

    myeveryheart 評論0 收藏0
  • es6基礎(chǔ)0x024:babel簡單使用

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

    wangbinke 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<