亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

深入理解函數(shù)執(zhí)行上下文 this

 更新時間:2022年10月24日 16:52:23   作者:叫蘇珊的_ikun  
這篇文章主要為大家介紹了深入理解函數(shù)執(zhí)行上下文 this示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

JavaScript 中的 this 是什么

關(guān)于 this,我們得先從執(zhí)行上下文說起。我們知道:執(zhí)行上下文中包含了變量環(huán)境、詞法環(huán)境、外部環(huán)境,當(dāng)然也包括 this,具體你可以參考下圖:

從圖中可以看出,this 是和執(zhí)行上下文綁定的,也就是說每個執(zhí)行上下文中都有一個 this。執(zhí)行上下文主要分為三種——全局執(zhí)行上下文、函數(shù)執(zhí)行上下文和 eval 執(zhí)行上下文,所以對應(yīng)的 this 也只有這三種——全局執(zhí)行上下文中的 this、函數(shù)中的 this 和 eval 中的 this。

不過由于 eval 我們使用的不多,所以本文我們對此就不做介紹了,如果你感興趣的話,可以自行搜索和學(xué)習(xí)相關(guān)知識。

那么接下來我們就重點講解下全局執(zhí)行上下文中的 this和函數(shù)執(zhí)行上下文中的 this。

全局執(zhí)行上下文中的 this

首先我們來看看全局執(zhí)行上下文中的 this 是什么。

你可以在控制臺中輸入console.log(this)來打印出來全局執(zhí)行上下文中的 this,最終輸出的是 window 對象。所以你可以得出這樣一個結(jié)論:全局執(zhí)行上下文中的 this 是指向 window 對象的。這也是 this 和作用域鏈的唯一交點,作用域鏈的最底端包含了 window 對象,全局執(zhí)行上下文中的 this 也是指向 window 對象。

函數(shù)執(zhí)行上下文中的 this

現(xiàn)在你已經(jīng)知道全局對象中的 this 是指向 window 對象了,那么接下來,我們就來重點分析函數(shù)執(zhí)行上下文中的 this。還是先看下面這段代碼:

function foo() {
  console.log(this);
}
foo();

我們在 foo 函數(shù)內(nèi)部打印出來 this 值,執(zhí)行這段代碼,打印出來的也是 window 對象,這說明在默認情況下調(diào)用一個函數(shù),其執(zhí)行上下文中的 this 也是指向 window 對象的。估計你會好奇,那能不能設(shè)置執(zhí)行上下文中的 this 來指向其他對象呢?答案是肯定的。通常情況下,有下面三種方式來設(shè)置函數(shù)執(zhí)行上下文中的 this 值。

1. 通過函數(shù)的 call 方法設(shè)置

你可以通過函數(shù)的call方法來設(shè)置函數(shù)執(zhí)行上下文的 this 指向,比如下面這段代碼,我們就并沒有直接調(diào)用 foo 函數(shù),而是調(diào)用了 foo 的 call 方法,并將 bar 對象作為 call 方法的參數(shù)。

let bar = {
  myName: " name1 ",
  test1: 1,
};
function foo() {
  this.myName = " name2 ";
}
foo.call(bar);
console.log(bar);
console.log(myName);

執(zhí)行這段代碼,然后觀察輸出結(jié)果,你就能發(fā)現(xiàn) foo 函數(shù)內(nèi)部的 this 已經(jīng)指向了 bar 對象,因為通過打印 bar 對象,可以看出 bar 的 myName 屬性已經(jīng)由“name1”變?yōu)?ldquo;name2”了,同時在全局執(zhí)行上下文中打印 myName,JavaScript 引擎提示該變量未定義。

其實除了 call 方法,你還可以使用bind和apply方法來設(shè)置函數(shù)執(zhí)行上下文中的 this,僅僅是語法稍有不同。

2. 通過對象調(diào)用方法設(shè)置

要改變函數(shù)執(zhí)行上下文中的 this 指向,除了通過函數(shù)的 call 方法來實現(xiàn)外,還可以通過對象調(diào)用的方式,比如下面這段代碼:

var myObj = {
  name: " name ",
  showThis: function () {
    console.log(this);
  },
};
myObj.showThis();

在這段代碼中,我們定義了一個 myObj 對象,該對象是由一個 name 屬性和一個 showThis 方法組成的,然后再通過 myObj 對象來調(diào)用 showThis 方法。執(zhí)行這段代碼,你可以看到,最終輸出的 this 值是指向 myObj 的。

所以,你可以得出這樣的結(jié)論:使用對象來調(diào)用其內(nèi)部的一個方法,該方法的 this 是指向?qū)ο蟊旧淼摹?/p>

其實,你也可以認為 JavaScript 引擎在執(zhí)行myObject.showThis()時,將其轉(zhuǎn)化為了:

myObj.showThis.call(myObj)

接下來我們稍微改變下調(diào)用方式,把 showThis 賦給一個全局對象,然后再調(diào)用該對象,代碼如下所示:

var myObj = {
  name: " time ",
  showThis: function () {
    this.name = " bang ";
    console.log(this);
  },
};
var foo = myObj.showThis;
foo();

執(zhí)行這段代碼,你會發(fā)現(xiàn) this 又指向了全局 window 對象。

所以通過以上兩個例子的對比,你可以得出下面這樣兩個結(jié)論:

  • 在全局環(huán)境中調(diào)用一個函數(shù),函數(shù)內(nèi)部的 this 指向的是全局變量 window。
  • 通過一個對象來調(diào)用其內(nèi)部的一個方法,該方法的執(zhí)行上下文中的 this 指向?qū)ο蟊旧怼?/li>

3. 通過構(gòu)造函數(shù)中設(shè)置

你可以像這樣設(shè)置構(gòu)造函數(shù)中的 this,如下面的示例代碼:

function CreateObj() {
  this.name = " time ";
}
var myObj = new CreateObj();

在這段代碼中,我們使用 new 創(chuàng)建了對象 myObj,那你知道此時的構(gòu)造函數(shù) CreateObj 中的 this 到底指向了誰嗎?

其實,當(dāng)執(zhí)行 new CreateObj() 的時候,JavaScript 引擎做了如下四件事:

  • 首先創(chuàng)建了一個空對象 tempObj;
  • 接著調(diào)用 CreateObj.call 方法,并將 tempObj 作為 call 方法的參數(shù),這樣當(dāng) CreateObj 的執(zhí)行上下文創(chuàng)建時,它的 this 就指向了 tempObj 對象;
  • 然后執(zhí)行 CreateObj 函數(shù),此時的 CreateObj 函數(shù)執(zhí)行上下文中的 this 指向了 tempObj 對象;
  • 最后返回 tempObj 對象。

這樣,我們就通過 new 關(guān)鍵字構(gòu)建好了一個新對象,并且構(gòu)造函數(shù)中的 this 其實就是新對象本身。

this 的設(shè)計缺陷以及應(yīng)對方案

就我個人而言,this 并不是一個很好的設(shè)計,因為它的很多使用方法都沖擊人的直覺,在使用過程中存在著非常多的坑。下面咱們就來一起看看那些 this 設(shè)計缺陷。

1. 嵌套函數(shù)中的 this 不會從外層函數(shù)中繼承

我認為這是一個嚴(yán)重的設(shè)計錯誤,并影響了很多開發(fā)者。

至于如何解決?你可以在函數(shù)中聲明一個變量 self 用來保存 this。當(dāng)然也可以使用 ES6 中的箭頭函數(shù)來解決這個問題。

2. 普通函數(shù)中的 this 默認指向全局對象 window

上面我們已經(jīng)介紹過了,在默認情況下調(diào)用一個函數(shù),其執(zhí)行上下文中的 this 是默認指向全局對象 window 的。

不過這個設(shè)計也是一種缺陷,因為在實際工作中,我們并不希望函數(shù)執(zhí)行上下文中的 this 默認指向全局對象,因為這樣會打破數(shù)據(jù)的邊界,造成一些誤操作。如果要讓函數(shù)執(zhí)行上下文中的 this 指向某個對象,最好的方式是通過 call 方法來顯示調(diào)用。

這個問題可以通過設(shè)置 JavaScript 的“嚴(yán)格模式”來解決。在嚴(yán)格模式下,默認執(zhí)行一個函數(shù),其函數(shù)的執(zhí)行上下文中的 this 值是 undefined,這就解決上面的問題了。

總結(jié)

回顧下內(nèi)容:

首先,在使用 this 時,為了避坑,你要謹(jǐn)記以下三點:

  • 當(dāng)函數(shù)作為對象的方法調(diào)用時,函數(shù)中的 this 就是該對象;
  • 當(dāng)函數(shù)被正常調(diào)用時,在嚴(yán)格模式下,this 值是 undefined,非嚴(yán)格模式下 this 指向的是全局對象 window;
  • 嵌套函數(shù)中的 this 不會繼承外層函數(shù)的 this 值。

最后,我們還提了一下箭頭函數(shù),因為箭頭函數(shù)沒有自己的執(zhí)行上下文,所以箭頭函數(shù)的 this 就是它外層函數(shù)的 this。

以上就是深入理解函數(shù)執(zhí)行上下文 this的詳細內(nèi)容,更多關(guān)于函數(shù)執(zhí)行上下文 this的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論