日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

JS高级——深入剖析函数中的this指向问题

發(fā)布時(shí)間:2024/7/5 javascript 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JS高级——深入剖析函数中的this指向问题 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、this到底指向什么呢?

我們先說一個(gè)最簡(jiǎn)單的,this在全局作用域下指向什么?

  • 這個(gè)問題非常容易回答,在瀏覽器中測(cè)試就是指向window

但是,開發(fā)中很少直接在全局作用于下去使用this,通常都是在函數(shù)中使用。

  • 所有的函數(shù)在被調(diào)用時(shí),都會(huì)創(chuàng)建一個(gè)執(zhí)行上下文:
  • 這個(gè)上下文中記錄著函數(shù)的調(diào)用棧、AO對(duì)象等;
  • this也是其中的一條記錄;

定義一個(gè)函數(shù),我們采用三種不同的方式對(duì)它進(jìn)行調(diào)用,它產(chǎn)生了三種不同的結(jié)果:

這個(gè)的案例可以給我們什么樣的啟示呢?

  • 函數(shù)在調(diào)用時(shí),JavaScript會(huì)默認(rèn)給this綁定一個(gè)值;
  • this的綁定和定義的位置(編寫的位置)沒有關(guān)系;
  • this的綁定和調(diào)用方式以及調(diào)用的位置有關(guān)系;
  • this是在運(yùn)行時(shí)被綁定的;
  • this到底是怎么樣的綁定規(guī)則呢?

    • 綁定一:默認(rèn)綁定;
    • 綁定二:隱式綁定;
    • 綁定三:顯示綁定;
    • 綁定四:new綁定;

    二、規(guī)則一:默認(rèn)綁定

    什么情況下使用默認(rèn)綁定呢?獨(dú)立函數(shù)調(diào)用。

    • 獨(dú)立的函數(shù)調(diào)用我們可以理解成函數(shù)沒有被綁定到某個(gè)對(duì)象上進(jìn)行調(diào)用;

    三、規(guī)則二:隱式綁定

    另外一種比較常見的調(diào)用方式是通過某個(gè)對(duì)象進(jìn)行調(diào)用的:

    • 也就是它的調(diào)用位置中,是通過某個(gè)對(duì)象發(fā)起的函數(shù)調(diào)用。



    四、規(guī)則三:顯示綁定

    隱式綁定有一個(gè)前提條件:

    • 必須在調(diào)用的對(duì)象內(nèi)部有一個(gè)對(duì)函數(shù)的引用(比如一個(gè)屬性);
    • 如果沒有這樣的引用,在進(jìn)行調(diào)用時(shí),會(huì)報(bào)找不到該函數(shù)的錯(cuò)誤;
    • 正是通過這個(gè)引用,間接的將this綁定到了這個(gè)對(duì)象上;

    如果我們不希望在 對(duì)象內(nèi)部 包含這個(gè)函數(shù)的引用,同時(shí)又希望在這個(gè)對(duì)象上進(jìn)行強(qiáng)制調(diào)用,該怎么做呢?

    • JavaScript所有的函數(shù)都可以使用call和apply方法(這個(gè)和Prototype有關(guān))。
      call和apply方法的區(qū)別其實(shí)非常簡(jiǎn)單,第一個(gè)參數(shù)是相同的,后面的參數(shù):apply為數(shù)組,call為參數(shù)列表;
    • 這兩個(gè)函數(shù)的第一個(gè)參數(shù)都要求是一個(gè)對(duì)象,這個(gè)對(duì)象的作用是什么呢?就是給this準(zhǔn)備的。
    • 在調(diào)用這個(gè)函數(shù)時(shí),會(huì)將this綁定到這個(gè)傳入的對(duì)象上。
    • 因?yàn)樯厦娴倪^程,我們明確的綁定了this指向的對(duì)象,所以稱之為 顯示綁定。

    通過call或者apply綁定this對(duì)象:

    如果我們希望一個(gè)函數(shù)總是顯示的綁定到一個(gè)對(duì)象上,可以怎么做呢?


    五、內(nèi)置函數(shù)的綁定思考

    有些時(shí)候,我們會(huì)調(diào)用一些JavaScript的內(nèi)置函數(shù),或者一些第三方庫(kù)中的內(nèi)置函數(shù)。

    • 這些內(nèi)置函數(shù)會(huì)要求我們傳入另外一個(gè)函數(shù);
    • 我們自己并不會(huì)顯示的調(diào)用這些函數(shù),而且JavaScript內(nèi)部或者第三方庫(kù)內(nèi)部會(huì)幫助我們執(zhí)行;
    • 這些函數(shù)中的this又是如何綁定的呢?

    setTimeout、數(shù)組的forEach、div的點(diǎn)擊:


    注意:forEach()第二個(gè)參數(shù)可以綁定this

    六、規(guī)則四:new綁定

    七、規(guī)則優(yōu)先級(jí)

    學(xué)習(xí)了四條規(guī)則,接下來開發(fā)中我們只需要去查找函數(shù)的調(diào)用應(yīng)用了哪條規(guī)則即可,但是如果一個(gè)函數(shù)調(diào)用位置應(yīng)用了多條規(guī)則,優(yōu)先級(jí)誰(shuí)更高呢?

    1.默認(rèn)規(guī)則的優(yōu)先級(jí)最低

    • 毫無疑問,默認(rèn)規(guī)則的優(yōu)先級(jí)是最低的,因?yàn)榇嬖谄渌?guī)則時(shí),就會(huì)通過其他規(guī)則的方式來綁定this

    2.顯示綁定優(yōu)先級(jí)高于隱式綁定


    3.new綁定優(yōu)先級(jí)高于隱式綁定

    4.new綁定優(yōu)先級(jí)高于bind

    • new綁定和call、apply是不允許同時(shí)使用的,所以不存在誰(shuí)的優(yōu)先級(jí)更高
    • new綁定可以和bind一起使用,new綁定優(yōu)先級(jí)更高

    八、this規(guī)則之外 – 忽略顯示綁定

    我們講到的規(guī)則已經(jīng)足以應(yīng)付平時(shí)的開發(fā),但是總有一些語(yǔ)法,超出了我們的規(guī)則之外。(神話故事和動(dòng)漫中總是有類似這樣的人物)

    如果在顯示綁定中,我們傳入一個(gè)null或者undefined,那么這個(gè)顯示綁定會(huì)被忽略,使用默認(rèn)規(guī)則:

    九、this規(guī)則之外 - 間接函數(shù)引用

    另外一種情況,創(chuàng)建一個(gè)函數(shù)的 間接引用,這種情況使用默認(rèn)綁定規(guī)則。

    • 賦值表達(dá)式(obj2.foo = obj1.foo)的結(jié)果是foo函數(shù);
    • foo函數(shù)被直接調(diào)用,那么是默認(rèn)綁定;

    十、箭頭函數(shù) arrow function

    箭頭函數(shù)是ES6之后增加的一種編寫函數(shù)的方法,并且它比函數(shù)表達(dá)式要更加簡(jiǎn)潔:

    • 箭頭函數(shù)不會(huì)綁定this、arguments屬性;
    • 箭頭函數(shù)不能作為構(gòu)造函數(shù)來使用(不能和new一起來使用,會(huì)拋出錯(cuò)誤);

    箭頭函數(shù)如何編寫呢?

    • (): 函數(shù)的參數(shù)
    • {}: 函數(shù)的執(zhí)行體

    十一、箭頭函數(shù)的編寫優(yōu)化

    十二、this規(guī)則之外 – ES6箭頭函數(shù)

    箭頭函數(shù)不使用this的四種標(biāo)準(zhǔn)規(guī)則(也就是不綁定this),而是根據(jù)外層作用域來決定this。

    我們來看一個(gè)模擬網(wǎng)絡(luò)請(qǐng)求的案例:

    • 這里我使用setTimeout來模擬網(wǎng)絡(luò)請(qǐng)求,請(qǐng)求到數(shù)據(jù)后如何可以存放到data中呢?

    • 我們需要拿到obj對(duì)象,設(shè)置data;

    • 但是直接拿到的this是window,

    • 我們需要在外層定義:var _this = this

    • 在setTimeout的回調(diào)函數(shù)中使用_this就代表了obj對(duì)象

      之前的代碼在ES6之前是我們最常用的方式,從ES6開始,我們會(huì)使用箭頭函數(shù):

    • 為什么在setTimeout的回調(diào)函數(shù)中可以直接使用this呢?

    • 因?yàn)榧^函數(shù)并不綁定this對(duì)象,那么this引用就會(huì)從上層作用于中找到對(duì)應(yīng)的this

    十三、面試題




    總結(jié)

    以上是生活随笔為你收集整理的JS高级——深入剖析函数中的this指向问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。