亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > JS > 正文

JavaScript箭頭函數中的this詳解

2024-05-06 16:52:24
字體:
來源:轉載
供稿:網友

前言

箭頭函數極大地簡化了this的取值規則。

普通函數與箭頭函數

普通函數指的是用function定義的函數:

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

箭頭函數指的是用=>定義的函數:

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

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

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

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

this到底是什么?

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

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與其他語言不一樣,并且它的取值還取決于代碼是否為嚴格模式("use strict")。

this的值是什么?

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

this就是代碼執行時當前的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.

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

這一條規則還是比較容易接受的。

Function context

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

函數中的this值取決于這個函數是怎樣被調用的,這一條規則就有點變態了,也是很容易出BUG的地方。

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

大家如果好奇的話,出門左轉看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.

當函數作為對象的方法被調用時,它的this值就是該對象。

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

self = this?

當我們需要在對象方法中嵌套一個內層函數時,this就會給我們帶來實際的困擾了,大家應該寫過這樣的代碼:

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

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

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

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

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

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

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

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

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

.bind(this)

我們也可以使用.bind(this)來規避this變來變去的問題:

// 使用.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),都不是什么很簡潔的方式。

總之,普通函數的this取值多少有點奇怪,尤其當我們采用面向對象的方式編程時,很多時候都需要用到this,大多數時候我們都不會去使用.bind(this),而是使用臨時變量self或者that來搬運this的取值,寫起來當然不是很爽,而且一不小心就會寫出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.

箭頭函數

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

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.

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

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

  • 對于需要使用object.method()方式調用的函數,使用普通函數定義,不要使用箭頭函數。對象方法中所使用的this值有確定的含義,指的就是object本身。
  • 其他情況下,全部使用箭頭函數。
// 使用箭頭函數var circle = {radius: 10,outerDiameter() {var innerDiameter = () => {console.log(2 * this.radius);};innerDiameter();}};circle.outerDiameter(); // 打印20

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

結論

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

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

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

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。


注:相關教程知識閱讀請移步到JavaScript/Ajax教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲一区二区久久久| 欧美日韩国产一区中文午夜| 亚洲 日韩 国产第一| 亚洲偷熟乱区亚洲香蕉av| 日本精品久久久久久久| 国产精品一区二区久久精品| 精品国产一区二区三区久久久狼| 亚洲国产精品成人va在线观看| 精品久久中文字幕| 91午夜在线播放| 国精产品一区一区三区有限在线| 日韩欧美在线免费| 欧美国产一区二区三区| 日韩电影网在线| 日韩av免费看| 91伊人影院在线播放| 91黑丝高跟在线| 欧美一级大胆视频| 亚洲精品xxxx| 亚洲精品视频在线观看视频| 亚洲sss综合天堂久久| 成人中文字幕在线观看| 亚洲精品短视频| 亚洲自拍偷拍视频| 国产精品入口夜色视频大尺度| 最新亚洲国产精品| 亚洲片在线资源| 久久久久久久久久亚洲| 国产午夜精品全部视频播放| 久热精品视频在线观看一区| 成人看片人aa| 国产福利视频一区二区| 午夜精品理论片| 国产成人自拍视频在线观看| 国产精品亚洲综合天堂夜夜| 三级精品视频久久久久| 亚洲天堂男人的天堂| 欧美亚洲一区在线| 亚洲国产成人精品女人久久久| 亚洲国产精品大全| 日韩国产精品亚洲а∨天堂免| 日本亚洲精品在线观看| 都市激情亚洲色图| 欧美成人午夜免费视在线看片| 国产精品久久久久久久一区探花| 国产精品午夜国产小视频| 国产成+人+综合+亚洲欧洲| 久久色免费在线视频| 国产精品白嫩美女在线观看| 久久免费国产精品1| 狠狠久久亚洲欧美专区| 欧美孕妇孕交黑巨大网站| 国产一区二区三区四区福利| 97在线视频免费看| 国产99久久精品一区二区永久免费| 日韩在线观看网站| 久久久久久有精品国产| 国产精品国产自产拍高清av水多| 国产精品www色诱视频| 午夜精品久久久久久久99黑人| 欧美日韩国产一中文字不卡| 欧美日韩加勒比精品一区| 日韩成人在线观看| 国产精品久久久久久久久久ktv| 亚洲毛茸茸少妇高潮呻吟| 久久久精品国产亚洲| 亚洲福利视频网站| 国产成人精品视频在线| 国产成人自拍视频在线观看| 亚洲精选在线观看| 日韩在线免费视频观看| 日韩综合视频在线观看| 伊人青青综合网站| 国产精品爽爽ⅴa在线观看| 91九色单男在线观看| 欧美综合第一页| 亚洲欧美一区二区精品久久久| 欧美激情综合色综合啪啪五月| 国产精品亚洲美女av网站| 亚洲视频专区在线| 日韩欧美国产骚| 中文字幕日韩在线视频| 久久久久久高潮国产精品视| 亚洲片av在线| 国产一区二区日韩精品欧美精品| 国产福利精品视频| 日韩av毛片网| 日本免费一区二区三区视频观看| 亚洲xxxx视频| 日韩福利在线播放| 国产欧美一区二区三区在线看| 国产日韩换脸av一区在线观看| 日韩在线观看视频免费| 亚洲美女免费精品视频在线观看| 91久久精品美女高潮| 国产丝袜一区二区三区免费视频| 成人欧美在线视频| 精品一区二区电影| 亚洲激情视频在线播放| 成人信息集中地欧美| 国产情人节一区| 国产98色在线| 国产精品你懂得| 高清在线视频日韩欧美| 国产成人精彩在线视频九色| 亚洲一区二区三区在线免费观看| 国外成人在线播放| 日韩中文娱乐网| 亚洲精品资源美女情侣酒店| 国产精品第一区| 亚洲欧美国产va在线影院| 日韩在线观看视频免费| 亚洲人成网站在线播| 91精品国产高清久久久久久91| 国产成人亚洲综合青青| 国产精品观看在线亚洲人成网| 亚洲人成网站色ww在线| 韩国一区二区电影| 日本伊人精品一区二区三区介绍| 91精品久久久久久久久青青| 精品国产一区二区三区在线观看| 日韩av手机在线看| 国产精品专区第二| 午夜美女久久久久爽久久| 欧美在线日韩在线| 亚洲第一页中文字幕| 亚洲欧洲黄色网| 狠狠躁夜夜躁人人爽天天天天97| 亚洲欧洲av一区二区| 亚洲高清久久久久久| 国外日韩电影在线观看| 欧美激情喷水视频| 久久久久久国产精品美女| 伦伦影院午夜日韩欧美限制| 奇米4444一区二区三区| 日韩日本欧美亚洲| 色综合色综合久久综合频道88| 久久久久亚洲精品成人网小说| 久久久爽爽爽美女图片| 懂色av一区二区三区| 国产精品扒开腿做| 亚洲精品久久在线| 国产精品极品美女在线观看免费| 7m第一福利500精品视频| 精品国产91乱高清在线观看| 91精品国产99久久久久久| 亚洲欧美日韩国产中文专区| 亚洲精品永久免费| 欧美专区在线视频| 亚洲www视频| www.久久色.com| 国产女人精品视频| 成人免费观看49www在线观看| 青草热久免费精品视频| 亚洲成年人在线播放| 欧美麻豆久久久久久中文| 在线免费观看羞羞视频一区二区| 欧美日韩加勒比精品一区| 国产国语videosex另类| 国产小视频91| 国产日本欧美一区| 国产丝袜精品第一页| 日本韩国欧美精品大片卡二| 国产小视频国产精品|