<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在物件內部的方法中使用物件內部的屬性是一個非常普遍的需求。但是 JavaScript 的作用域機制並不支援這一點,基於這個需求,JavaScript 有另外一套 this 機制。
this 是和執行上下文繫結的,也就是說每個執行上下文中都有一個 this。執行上下文主要分為三種——全域性執行上下文、函數執行上下文和 eval 執行上下文,所以對應的 this 也只有這三種——全域性執行上下文中的 this、函數中的 this 和 eval 中的 this。
全域性執行上下文中的 this
是指向 window
物件的。這也是 this
和作用域鏈的 唯一交點,作用域鏈的最底端包含了 window
物件,全域性執行上下文中的 this
也是指向 window
物件。
function foo() { console.log(this); } foo();
執行這段程式碼,列印出來的也是 window
物件,這說明在預設情況下呼叫一個函數,其執行上下文中的 this
也是指向 window
物件的。
通常情況下,有下面三種方式來設定函數執行上下文中的 this
值:
1. 通過函數的 call 方法設定
let bar = { myName: "極客邦", test1: 1, }; function foo() { this.myName = "極客時間"; } foo.call(bar); console.log(bar); console.log(myName);
執行這段程式碼,你就能發現 foo
函數內部的 this
已經指向了 bar
物件,因為通過列印 bar
物件,可以看出 bar
的 myName
屬性已經由“極客邦”變為“極客時間”了,同時在全域性執行上下文中列印 myName
,JavaScript 引擎提示該變數未定義。其實除了 call
方法,你還可以使用 bind
和 apply
方法來設定函數執行上下文中的 this
。
2. 通過物件呼叫方法設定
var myObj = { name: "極客時間", showThis: function () { console.log(this); }, }; myObj.showThis();
執行這段程式碼,你可以看到,最終輸出的 this
值是指向 myObj
的。所以,你可以得出這樣的結論:使用物件來呼叫其內部的一個方法,該方法的 this
是指向物件本身的。
接下來我們稍微改變下呼叫方式,把 showThis
賦給一個全域性物件,然後再呼叫該物件,程式碼如下所示:
var myObj = { name: "極客時間", showThis: function () { this.name = "極客邦"; console.log(this); }, }; var foo = myObj.showThis; foo();
執行這段程式碼,你會發現 this
又指向了全域性 window
物件。
結論:
在全域性環境中呼叫一個函數,函數內部的 this
指向的是全域性變數 window
。
通過一個物件來呼叫其內部的一個方法,該方法的執行上下文中的 this
指向物件本身。
3. 通過建構函式中設定
function CreateObj() { this.name = "極客時間"; } var myObj = new CreateObj();
當執行 new CreateObj()
的時候,JavaScript 引擎做了如下四件事:
首先建立了一個空物件 tempObj
接著呼叫 CreateObj.call
方法,並將 tempObj
作為 call
方法的引數,這樣當 CreateObj
的執行上下文建立時,它的 this
就指向了 tempObj
物件
然後執行 CreateObj
函數,此時的 CreateObj
函數執行上下文中的 this
指向了 tempObj
物件
最後返回 tempObj
物件
var tempObj = {}; CreateObj.call(tempObj); return tempObj;
這樣,就通過 new
關鍵字構建好了一個新物件,並且建構函式中的 this
其實就是新物件本身。
var myObj = { name: "極客時間", showThis: function () { console.log(this); function bar() { console.log(this); } bar(); }, }; myObj.showThis();
執行這段程式碼後,會發現函數 bar
中的 this
指向的是全域性 window
物件,而函數 showThis
中的 this
指向的是 myObj
物件。
可以通過一個小技巧來解決這個問題,比如在 showThis
函數中宣告一個變數 that
用來儲存 this
,然後在 bar
函數中使用 that
。其實,這個方法的的本質是把 this
體系轉換為了作用域的體系。
其實,你也可以使用 ES6 中的箭頭函數來解決這個問題:
var myObj = { name: "極客時間", showThis: function () { console.log(this); var bar = () => { console.log(this); }; bar(); }, }; myObj.showThis();
這是因為 ES6 中的箭頭函數並不會建立其自身的執行上下文,所以箭頭函數中的 this
取決於它的外部函數。
在實際工作中,我們並不希望函數執行上下文中的 this
預設指向全域性物件,因為這樣會打破資料的邊界,造成一些誤操作。如果要讓函數執行上下文中的 this
指向某個物件,最好的方式是通過 call
方法來顯示呼叫。
可以通過設定 JavaScript 的 嚴格模式 來解決(在第一行加上 "use strict";
)。在嚴格模式下,預設執行一個函數,其函數的執行上下文中的 this
值是 undefined
。
以上就是JavaScript 執行上下文的視角詳解this使用的詳細內容,更多關於JavaScript 執行上下文 this的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45