您好,登錄后才能下訂單哦!
這篇文章主要講解了“JavaScript執(zhí)行上下文中的this怎么使用”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“JavaScript執(zhí)行上下文中的this怎么使用”吧!
在對(duì)象內(nèi)部的方法中使用對(duì)象內(nèi)部的屬性是一個(gè)非常普遍的需求。但是 JavaScript 的作用域機(jī)制并不支持這一點(diǎn),基于這個(gè)需求,JavaScript 有另外一套 this 機(jī)制。
this 是和執(zhí)行上下文綁定的,也就是說(shuō)每個(gè)執(zhí)行上下文中都有一個(gè) this。執(zhí)行上下文主要分為三種——全局執(zhí)行上下文、函數(shù)執(zhí)行上下文和 eval 執(zhí)行上下文,所以對(duì)應(yīng)的 this 也只有這三種——全局執(zhí)行上下文中的 this、函數(shù)中的 this 和 eval 中的 this。
全局執(zhí)行上下文中的 this
是指向 window
對(duì)象的。這也是 this
和作用域鏈的 唯一交點(diǎn),作用域鏈的最底端包含了 window
對(duì)象,全局執(zhí)行上下文中的 this
也是指向 window
對(duì)象。
function foo() { console.log(this); } foo();
執(zhí)行這段代碼,打印出來(lái)的也是 window
對(duì)象,這說(shuō)明在默認(rèn)情況下調(diào)用一個(gè)函數(shù),其執(zhí)行上下文中的 this
也是指向 window
對(duì)象的。
通常情況下,有下面三種方式來(lái)設(shè)置函數(shù)執(zhí)行上下文中的 this
值:
1. 通過(guò)函數(shù)的 call 方法設(shè)置
let bar = { myName: "極客邦", test1: 1, }; function foo() { this.myName = "極客時(shí)間"; } foo.call(bar); console.log(bar); console.log(myName);
執(zhí)行這段代碼,你就能發(fā)現(xiàn) foo
函數(shù)內(nèi)部的 this
已經(jīng)指向了 bar
對(duì)象,因?yàn)橥ㄟ^(guò)打印 bar
對(duì)象,可以看出 bar
的 myName
屬性已經(jīng)由“極客邦”變?yōu)椤皹O客時(shí)間”了,同時(shí)在全局執(zhí)行上下文中打印 myName
,JavaScript 引擎提示該變量未定義。其實(shí)除了 call
方法,你還可以使用 bind
和 apply
方法來(lái)設(shè)置函數(shù)執(zhí)行上下文中的 this
。
2. 通過(guò)對(duì)象調(diào)用方法設(shè)置
var myObj = { name: "極客時(shí)間", showThis: function () { console.log(this); }, }; myObj.showThis();
執(zhí)行這段代碼,你可以看到,最終輸出的 this
值是指向 myObj
的。所以,你可以得出這樣的結(jié)論:使用對(duì)象來(lái)調(diào)用其內(nèi)部的一個(gè)方法,該方法的 this
是指向?qū)ο蟊旧淼摹?/p>
接下來(lái)我們稍微改變下調(diào)用方式,把 showThis
賦給一個(gè)全局對(duì)象,然后再調(diào)用該對(duì)象,代碼如下所示:
var myObj = { name: "極客時(shí)間", showThis: function () { this.name = "極客邦"; console.log(this); }, }; var foo = myObj.showThis; foo();
執(zhí)行這段代碼,你會(huì)發(fā)現(xiàn) this
又指向了全局 window
對(duì)象。
結(jié)論:
在全局環(huán)境中調(diào)用一個(gè)函數(shù),函數(shù)內(nèi)部的 this
指向的是全局變量 window
。
通過(guò)一個(gè)對(duì)象來(lái)調(diào)用其內(nèi)部的一個(gè)方法,該方法的執(zhí)行上下文中的 this
指向?qū)ο蟊旧怼?/p>
3. 通過(guò)構(gòu)造函數(shù)中設(shè)置
function CreateObj() { this.name = "極客時(shí)間"; } var myObj = new CreateObj();
當(dāng)執(zhí)行 new CreateObj()
的時(shí)候,JavaScript 引擎做了如下四件事:
首先創(chuàng)建了一個(gè)空對(duì)象 tempObj
接著調(diào)用 CreateObj.call
方法,并將 tempObj
作為 call
方法的參數(shù),這樣當(dāng) CreateObj
的執(zhí)行上下文創(chuàng)建時(shí),它的 this
就指向了 tempObj
對(duì)象
然后執(zhí)行 CreateObj
函數(shù),此時(shí)的 CreateObj
函數(shù)執(zhí)行上下文中的 this
指向了 tempObj
對(duì)象
最后返回 tempObj
對(duì)象
var tempObj = {}; CreateObj.call(tempObj); return tempObj;
這樣,就通過(guò) new
關(guān)鍵字構(gòu)建好了一個(gè)新對(duì)象,并且構(gòu)造函數(shù)中的 this
其實(shí)就是新對(duì)象本身。
var myObj = { name: "極客時(shí)間", showThis: function () { console.log(this); function bar() { console.log(this); } bar(); }, }; myObj.showThis();
執(zhí)行這段代碼后,會(huì)發(fā)現(xiàn)函數(shù) bar
中的 this
指向的是全局 window
對(duì)象,而函數(shù) showThis
中的 this
指向的是 myObj
對(duì)象。
可以通過(guò)一個(gè)小技巧來(lái)解決這個(gè)問(wèn)題,比如在 showThis
函數(shù)中聲明一個(gè)變量 that
用來(lái)保存 this
,然后在 bar
函數(shù)中使用 that
。其實(shí),這個(gè)方法的的本質(zhì)是把 this
體系轉(zhuǎn)換為了作用域的體系。
其實(shí),你也可以使用 ES6 中的箭頭函數(shù)來(lái)解決這個(gè)問(wèn)題:
var myObj = { name: "極客時(shí)間", showThis: function () { console.log(this); var bar = () => { console.log(this); }; bar(); }, }; myObj.showThis();
這是因?yàn)?ES6 中的箭頭函數(shù)并不會(huì)創(chuàng)建其自身的執(zhí)行上下文,所以箭頭函數(shù)中的 this
取決于它的外部函數(shù)。
在實(shí)際工作中,我們并不希望函數(shù)執(zhí)行上下文中的 this
默認(rèn)指向全局對(duì)象,因?yàn)檫@樣會(huì)打破數(shù)據(jù)的邊界,造成一些誤操作。如果要讓函數(shù)執(zhí)行上下文中的 this
指向某個(gè)對(duì)象,最好的方式是通過(guò) call
方法來(lái)顯示調(diào)用。
可以通過(guò)設(shè)置 JavaScript 的 嚴(yán)格模式 來(lái)解決(在第一行加上 "use strict";
)。在嚴(yán)格模式下,默認(rèn)執(zhí)行一個(gè)函數(shù),其函數(shù)的執(zhí)行上下文中的 this
值是 undefined
。
感謝各位的閱讀,以上就是“JavaScript執(zhí)行上下文中的this怎么使用”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)JavaScript執(zhí)行上下文中的this怎么使用這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。