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

資訊專欄INFORMATION COLUMN

JavaScript深入淺出第1課:箭頭函數(shù)中的this究竟是什么鬼?

MRZYD / 1222人閱讀

摘要:箭頭函數(shù)沒有自己的值,箭頭函數(shù)中所使用的來自于函數(shù)作用域鏈。使用箭頭函數(shù)打印對于內(nèi)層函數(shù),它本身并沒有值,其使用的來自作用域鏈,來自更高層函數(shù)的作用域。

《JavaScript 深入淺出》系列

JavaScript 深入淺出第 1 課:箭頭函數(shù)中的 this 究竟是什么鬼?

JavaScript 深入淺出第 2 課:函數(shù)是一等公民是什么意思呢?

普通函數(shù)與箭頭函數(shù)

普通函數(shù)指的是用function定義的函數(shù):

var hello = function () {
    console.log("Hello, Fundebug!");
}

箭頭函數(shù)指的是用=>定義的函數(shù):

var hello = () => {
    console.log("Hello, Fundebug!");
}

JavaScript箭頭函數(shù)與普通函數(shù)不只是寫法上的區(qū)別,它們還有一些微妙的不同點,其中一個不同點就是this。

箭頭函數(shù)沒有自己的this值,箭頭函數(shù)中所使用的this來自于函數(shù)作用域鏈。

這句話很簡單,不過聽著稍微有點莫名其妙,得從頭說起。

this到底是什么?

關(guān)于this的文章也夠多了,有時候越描越黑,我就不再添亂了,我只負(fù)責(zé)搬運一下MDN文檔:this,感興趣的可以仔細(xì)閱讀一下,我摘錄一些最重要的話就好了。

A function"s this keyword behaves a little differently in JavaScript compared to other languages. It also has some differences between strict mode and non-strict mode.

JavaScript是一門比較奇特的語言,它的this與其他語言不一樣,并且它的取值還取決于代碼是否為嚴(yán)格模式("use strict")。

this的值是什么?

The JavaScript context object in which the current code is executing.

this就是代碼執(zhí)行時當(dāng)前的context object。

Global context

In the global execution context (outside of any function), this refers to the global object whether in strict mode or not.

代碼沒有在任何函數(shù)中執(zhí)行,而是在全局作用域中執(zhí)行時,this的值就是global對象,對于瀏覽器來說,this就是window。

這一條規(guī)則還是比較容易接受的。

Function context

Inside a function, the value of this depends on how the function is called.

函數(shù)中的this值取決于這個函數(shù)是怎樣被調(diào)用的,這一條規(guī)則就有點{{BANNED}}了,也是很容易出BUG的地方。

另外,this的值還與函數(shù)是否為嚴(yán)格模式("use strict")有關(guān),這就非常的喪心病狂了...

大家如果好奇的話,出門左轉(zhuǎn)看MDN文檔,我多說無益,只說明一種簡單的情況。

As an object method

When a function is called as a method of an object, its this is set to the object the method is called on.

當(dāng)函數(shù)作為對象的方法被調(diào)用時,它的this值就是該對象。

var circle = {
    radius: 10,
    getRadius() {
        console.log(this.radius);
    }
};

circle.getRadius(); // 打印 10
self = this?

當(dāng)我們需要在對象方法中嵌套一個內(nèi)層函數(shù)時,this就會給我們帶來實際的困擾了,大家應(yīng)該寫過這樣的代碼:

// 使用臨時變量self
var circle = {
    radius: 10,
    outerDiameter() {
        var self = this;
        var innerDiameter = function() {
            console.log(2 * self.radius);
        };
        innerDiameter();
    }
};

circle.outerDiameter(); // 打印20

outerDiameter函數(shù)是circle對象的方法,因此其this值就是circle對象。

那我們直接寫this.radius多好啊,可惜不能這么寫,因為內(nèi)層函數(shù)innerDiameter并不會繼承外層函數(shù)outerDiameter的this值。outerDiameter函數(shù)的this值就是circle對象,this.radius等于10。

但是,innerDiameter函數(shù)的this值不是circle對象,那它到底是啥?它是innerDiameter函數(shù)執(zhí)行時當(dāng)前的context object,這個context object又是啥?其實我也暈了,所以不妨測試一下:

// innerDiameter函數(shù)中的this是window
var circle = {
    radius: 10,
    outerDiameter() {
        var innerDiameter = function() {
            console.log(this === window);
        };
        innerDiameter();
    }
};

circle.outerDiameter(); // 打印true

innerDiameter函數(shù)中的this是window,為啥是window這個不去管它,反正不是circle對象。

因此,如果我們直接在innerDiameter函數(shù)中使用this的話,就出問題了:

// 使用普通函數(shù)
var circle = {
    radius: 10,
    outerDiameter() {
        var innerDiameter = function() {
            console.log(2 * this.radius);
        };
        innerDiameter();
    }
};

circle.outerDiameter(); // 打印NaN

于是,我們不得不使用一個臨時變量self將外層函數(shù)outerDiameter的this值搬運到內(nèi)層函數(shù)innerDiameter。

.bind(this)

我們也可以使用.bind(this)來規(guī)避this變來變?nèi)サ膯栴}:

// 使用.bind(this)
var circle = {
    radius: 10,
    outerDiameter() {
        var innerDiameter = function() {
            console.log(2 * this.radius);
        };
        innerDiameter = innerDiameter.bind(this);
        innerDiameter();
    }
};

circle.outerDiameter(); // 打印20

但是,無論是使用臨時變量self,還是使用.bind(this),都不是什么很簡潔的方式。

總之,普通函數(shù)的this取值多少有點奇怪,尤其當(dāng)我們采用面向?qū)ο蟮姆绞骄幊虝r,很多時候都需要用到this,大多數(shù)時候我們都不會去使用.bind(this),而是使用臨時變量self或者that來搬運this的取值,寫起來當(dāng)然不是很爽,而且一不小心就會寫出BUG來。

正如MDN文檔所說:

Until arrow functions, every new function defined its own this value based on how the function was called。This proved to be less than ideal with an object-oriented style of programming.
箭頭函數(shù)

箭頭函數(shù)的this取值,規(guī)則非常簡單,因為this在箭頭函數(shù)中,可以看做一個普通變量。

An arrow function does not have its own this. The this value of the enclosing lexical scope is used; arrow functions follow the normal variable lookup rules.

箭頭函數(shù)沒有自己的this值,箭頭函數(shù)中所使用的this都是來自函數(shù)作用域鏈,它的取值遵循普通普通變量一樣的規(guī)則,在函數(shù)作用域鏈中一層一層往上找。

有了箭頭函數(shù),我只要遵守下面的規(guī)則,this的問題就可以基本上不用管了:

對于需要使用object.method()方式調(diào)用的函數(shù),使用普通函數(shù)定義,不要使用箭頭函數(shù)。對象方法中所使用的this值有確定的含義,指的就是object本身。

其他情況下,全部使用箭頭函數(shù)。

// 使用箭頭函數(shù)
var circle = {
    radius: 10,
    outerDiameter() {
        var innerDiameter = () => {
            console.log(2 * this.radius);
        };
        innerDiameter();
    }
};

circle.outerDiameter(); // 打印20

對于內(nèi)層函數(shù)innerDiameter,它本身并沒有this值,其使用的this來自作用域鏈,來自更高層函數(shù)的作用域。innerDiameter的外層函數(shù)outerDiameter是普通函數(shù),它是有this值的,它的this值就是circle對象。因此,innerDiameter函數(shù)中所使用的this來自outerDiameter函數(shù),其值為circle對象。

結(jié)論

JavaScript是Brendan Eich花了10天時間設(shè)計出來的,因此各種莫名其妙的特性,this也算是其中一個奇葩。好在這些年ECMAScript標(biāo)準(zhǔn)發(fā)展很快也很穩(wěn)定,每年擼一個新的標(biāo)準(zhǔn),多少可以彌補一下JS的先天不足。

箭頭函數(shù)對于this取值規(guī)則的簡化,其實也就是為了少給大家添亂,誰能記得住普通函數(shù)this取值的那么多條條框框啊。。。

另外,MDN文檔絕對是一個寶藏,大家可以多看看。

關(guān)于JS,我打算開始寫一個系列的博客,大家還有啥不太清楚的地方?不妨留言一下,我可以研究一下,然后再與大家分享一下。也大家歡迎添加我的個人微信(KiwenLau),我是Fundebug的技術(shù)負(fù)責(zé)人,一個對JS又愛又恨的程序員。

參考

ES6 In Depth: Arrow functions

MDN文檔 - this

關(guān)于Fundebug

Fundebug專注于JavaScript、微信小程序、微信小游戲、支付寶小程序、React Native、Node.js和Java線上應(yīng)用實時BUG監(jiān)控。 自從2016年雙十一正式上線,F(xiàn)undebug累計處理了10億+錯誤事件,付費客戶有陽光保險、核桃編程、荔枝FM、掌門1對1、微脈、青團(tuán)社等眾多品牌企業(yè)。歡迎大家免費試用!

版權(quán)聲明

轉(zhuǎn)載時請注明作者 Fundebug以及本文地址:https://blog.fundebug.com/201...

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

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

相關(guān)文章

  • JavaScript深入淺出2函數(shù)是一等公民是什么意思呢?

    摘要:函數(shù)是一等公民,是什么意思呢我來與大家探討一下,拋磚引玉。對于來說,函數(shù)可以賦值給變量,也可以作為函數(shù)參數(shù),還可以作為函數(shù)返回值,因此中函數(shù)是一等公民。也就是說,函數(shù)為第一公民是函數(shù)式編程的必要條件。 摘要: 聽起來很炫酷的一等公民是啥? 《JavaScript深入淺出》系列: JavaScript深入淺出第1課:箭頭函數(shù)中的this究竟是什么鬼? JavaScript深入淺出第2課...

    wmui 評論0 收藏0
  • JavaScript深入淺出3什么是垃圾回收算法?

    摘要:摘要是如何回收內(nèi)存的深入淺出系列深入淺出第課箭頭函數(shù)中的究竟是什么鬼深入淺出第課函數(shù)是一等公民是什么意思呢深入淺出第課什么是垃圾回收算法最近垃圾回收這個話題非?;?,大家不能隨隨便便的扔垃圾了,還得先分類,這樣方便對垃圾進(jìn)行回收再利用。 摘要: JS是如何回收內(nèi)存的? 《JavaScript深入淺出》系列: JavaScript深入淺出第1課:箭頭函數(shù)中的this究竟是什么鬼? Jav...

    AaronYuan 評論0 收藏0
  • JavaScript深入淺出4:V8引擎是如何工作的?

    摘要:摘要性能彪悍的引擎。深入淺出系列深入淺出第課箭頭函數(shù)中的究竟是什么鬼深入淺出第課函數(shù)是一等公民是什么意思呢深入淺出第課什么是垃圾回收算法深入淺出第課是如何工作的最近,生態(tài)系統(tǒng)又多了個非常硬核的項目。 摘要: 性能彪悍的V8引擎。 《JavaScript深入淺出》系列: JavaScript深入淺出第1課:箭頭函數(shù)中的this究竟是什么鬼? JavaScript深入淺出第2課:函數(shù)是一...

    hsluoyz 評論0 收藏0
  • JavaScript深入淺出5:Chrome是如何成功的?

    摘要:所做的最重要的事情,就是對成千上萬的網(wǎng)頁進(jìn)行排序,所以它存在的意義是基于網(wǎng)頁的。確實有很多非常成功的產(chǎn)品,比如,,,但是它們其實都是收購來的。為什么呢因為要做到極簡主義,需要深刻思考用戶需求以及產(chǎn)品價值。 摘要: Chrome改變世界。 《JavaScript深入淺出》系列: JavaScript深入淺出第1課:箭頭函數(shù)中的this究竟是什么鬼? JavaScript深入淺出第2課:...

    luqiuwen 評論0 收藏0
  • 關(guān)于 this 你想知道的一切都在這里

    摘要:如下在第一個例子中,被點擊元素是通過,這個形式參數(shù)來代替的。它的作用和形式參數(shù)類似,其本質(zhì)上是一個對象的引用,它的特殊性在于不需要手動傳值,所以使用起來會更加簡單和方便。 無論在 javascript 的日常使用中還是前端面試過程中,this 的出鏡率都極高。這無疑說明了,this 的重要性。但是 this 非常靈活,導(dǎo)致很多人覺得 this 的行為難以理解。本文從為什么要有 this...

    Lemon_95 評論0 收藏0

發(fā)表評論

0條評論

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