摘要:關(guān)鍵字是中一個復(fù)雜的機制,它被自動定義在所有的函數(shù)作用域中。指向它自身匿名函數(shù)無法指向自身第一個函數(shù)被稱為具名函數(shù),在它內(nèi)部可以使用來引用自身。的綁定和函數(shù)聲明的位置沒有任何關(guān)系,取決于函數(shù)的調(diào)用方式。這是理解的前提。
this關(guān)鍵字是JavaScript中一個復(fù)雜的機制,它被自動定義在所有的函數(shù)作用域中。
1. 為什么要用thisfunction identify() { return this.name.toUpperCase() } function speak() { var greeting = "hello, i"am" + identify.call(this) console.log(greeting) } var me = { name: "Kyle" } var you = { name: "Reader" } identify.call(me); //KYLE identify.call(you) //READER speak.call(me) //Hello, 我是KYLE speak.call(you) //Hello, 我是READER
上面這部分代碼在不同的上下文對象中重復(fù)使用identify()和speak(),不用針對每個對象編寫不同版本的函數(shù)。
如果不使用this,那就需要給identify()和speak()顯示傳入一個上下文對象。
function identify(context) { return context.name.toUpperCase(); } function speak(context) { var greeting = "Hello i"am" + identify(context) console.log(greeting) } identify(you) //READER speak(me) //hello, 我是KYLE
然而,this提供了一種更優(yōu)雅的方式來隱式傳遞一個對象引用,因此可以將API設(shè)計的更加簡潔且易于復(fù)用。
當(dāng)你的代碼越來越復(fù)雜的時候,顯示的傳遞上下文對象會變得很混亂。
通常會將this理解成指向函數(shù)自身。平常我們會在函數(shù)內(nèi)部調(diào)用自身(例如遞歸)。在JavaScript中函數(shù)也是一個對象,那么我們可以在調(diào)用函數(shù)的時候存儲狀態(tài)(屬性的值)。
我們看下以下代碼,會發(fā)現(xiàn)this并沒有指向函數(shù)本身:
//記錄foo的調(diào)用次數(shù) function foo(num) { console.log("foo: "+ num) this.count ++ } foo.count = 0; var i; for(i=0; i<10; i++) { if(i>5) { foo(i) } } //foo: 6 //foo: 7 //foo: 8 //foo: 9 //foo 被調(diào)用了多少次? console.log(foo.count) //0
可以看到foo()執(zhí)行了4次,但是foo.count仍然是0,所以從字面上理解this指向的是當(dāng)前函數(shù)自身就是錯誤的!
在執(zhí)行foo.count=0的時候,確實向函數(shù)對象foo添加了一個count屬性,但是函數(shù)內(nèi)部的this.count的this并不是指向那個函數(shù)對象(其實是window對象)。
那么增加的是哪個count?這是創(chuàng)建在全局變量的一個count,值為NaN.
如果要從函數(shù)對象內(nèi)部引用它自身,那只使用this是不夠的。一般你需要通過一個指向函數(shù)對象的詞法標(biāo)識符來引用。
function foo() { foo.count = 4 //foo指向它自身 } setTimeout(function() { //匿名函數(shù)無法指向自身 }, 10)
第一個函數(shù)被稱為具名函數(shù),在它內(nèi)部可以使用foo來引用自身。但是在第二個例子中,傳入setTimeout(..)的回調(diào)函數(shù)沒有名稱標(biāo)識符,因此無法從函數(shù)內(nèi)部引用自身。
還有一種方法是通過強制this指向foo函數(shù)對象:
function foo(num) { console.log("foo:" + num) this.count ++ } foo.count = 0 var i; for(i=0; i<10; i++) { if(i>5) { foo.call(foo, i) } }
如上,我們強制this指向了foo,這樣就可以獲得我們想要的答案了。
誤解之它的作用域第二種錯誤的理解是this指向函數(shù)的作用域。這個問題有些復(fù)雜,因為在某種情況下它是正確的。
需要明確的是,this在任何情況下都不指向函數(shù)的詞法作用域。在JavaScript內(nèi)部,作用域確實很像對象,可見的標(biāo)識符都是它的屬性。但是作用域?qū)ο笫菬o法通過JavaScript代碼進(jìn)行訪問,它是在JavaScript引擎內(nèi)部。
function foo() { var a = 2; this.bar(); } function bar() { console.log(this.a) } foo(); // a is not defined
以上代碼運行是不會得到你理想的結(jié)果的,因為你不能使用this來引用一個詞法作用域內(nèi)部的東西。
3. this到底是什么this是在運行時進(jìn)行綁定的,并不是在編寫時綁定,它的上下文取決于函數(shù)調(diào)用時的各種條件。this的綁定和函數(shù)聲明的位置沒有任何關(guān)系,取決于函數(shù)的調(diào)用方式。
當(dāng)一個函數(shù)調(diào)用時,會創(chuàng)建一個活動記錄(有時候也稱為執(zhí)行上下文)。這個記錄 會包含函數(shù)在哪里被調(diào)用(調(diào)用棧),函數(shù)的調(diào)用方法,傳入的參數(shù)信息。this就是記錄的其中一個屬性,會在函數(shù)執(zhí)行的過程中用到。
總結(jié)這里我們要明白this既不是指向函數(shù)自身,也不是指向函數(shù)的詞法作用域。這是理解this的前提。
this實際上時在函數(shù)被調(diào)用時發(fā)生的綁定,它指向什么完全取決于函數(shù)在哪里被調(diào)用。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/89948.html
摘要:找到函數(shù)的調(diào)用位置最重要的是要分析調(diào)用棧就是為了到達(dá)當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù)。顯示綁定我們可以使用函數(shù)的和方法,通過這兩個方法可以在某個對象上強制調(diào)用函數(shù)。 在上一篇我們了解過每個函數(shù)的this是在調(diào)用的時候綁定的,完全卻決于函數(shù)的調(diào)用位置(也就是函數(shù)的調(diào)用方法)。 1. 調(diào)用位置 在理解this的綁定過程之前,首先要理解調(diào)用位置:調(diào)用位置就是函數(shù)在代碼中被調(diào)用的位置,而不是聲明的...
摘要:下面開始分析開頭的代碼第一輪事件循環(huán)流程整體作為第一個宏任務(wù)進(jìn)入主線程,遇到,輸出遇到函數(shù)聲明,聲明暫時不用管遇到,其回調(diào)函數(shù)被分發(fā)到微任務(wù)中。我們記為遇到,其回調(diào)函數(shù)被分發(fā)到宏任務(wù)中。 先上一道常見的筆試題 console.log(1); async function async1() { console.log(2); await async2(); con...
摘要:下面開始分析開頭的代碼第一輪事件循環(huán)流程整體作為第一個宏任務(wù)進(jìn)入主線程,遇到,輸出遇到函數(shù)聲明,聲明暫時不用管遇到,其回調(diào)函數(shù)被分發(fā)到微任務(wù)中。我們記為遇到,其回調(diào)函數(shù)被分發(fā)到宏任務(wù)中。 先上一道常見的筆試題 console.log(1); async function async1() { console.log(2); await async2(); con...
摘要:是什么本質(zhì)是一個綁定,在函數(shù)被調(diào)用時建立。它的指向是完全由函數(shù)被調(diào)用的調(diào)用點來決定的。因為函數(shù)的調(diào)用點在全局作用域,所以指向全局變量這里就是函數(shù)的調(diào)用點存在的意義在函數(shù)體內(nèi)部指代函數(shù)當(dāng)前的運行環(huán)境。從而實現(xiàn)干凈的設(shè)計和更容易的復(fù)用。 this是什么? this 本質(zhì)是一個綁定, 在函數(shù)被調(diào)用時建立。它的指向是完全由函數(shù)被調(diào)用的調(diào)用點來決定的。 function baz() { ...
摘要:而小程序官方的是在中調(diào)用方法來改變數(shù)據(jù),從而改變界面。為了寫測試讓咱們來重構(gòu)一把,利用學(xué)習(xí)過的函數(shù)式編程中的高階函數(shù)把依賴注入。也就是說當(dāng)中的某個數(shù)據(jù)更新的時候,我們并不知道它會影響哪個中的屬性,特別的還有依賴于的情況。 眾所周知 Vue 是借助 ES5 的 Object.defineProperty 方法設(shè)置 getter、setter 達(dá)到數(shù)據(jù)驅(qū)動界面,當(dāng)然其中還有模板編譯等等其他...
閱讀 2879·2021-10-14 09:50
閱讀 1227·2021-10-08 10:21
閱讀 3661·2021-10-08 10:16
閱讀 3067·2021-09-27 14:02
閱讀 3142·2021-09-23 11:21
閱讀 2127·2021-09-07 10:17
閱讀 413·2019-08-30 14:00
閱讀 2117·2019-08-29 17:26