亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

JavaScript中this終極理解(1)

YacaToy / 2648人閱讀

摘要:關(guān)鍵字是中一個(gè)復(fù)雜的機(jī)制,它被自動(dòng)定義在所有的函數(shù)作用域中。指向它自身匿名函數(shù)無法指向自身第一個(gè)函數(shù)被稱為具名函數(shù),在它內(nèi)部可以使用來引用自身。的綁定和函數(shù)聲明的位置沒有任何關(guān)系,取決于函數(shù)的調(diào)用方式。這是理解的前提。

this關(guān)鍵字是JavaScript中一個(gè)復(fù)雜的機(jī)制,它被自動(dòng)定義在所有的函數(shù)作用域中。

1. 為什么要用this
function 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

上面這部分代碼在不同的上下文對(duì)象中重復(fù)使用identify()和speak(),不用針對(duì)每個(gè)對(duì)象編寫不同版本的函數(shù)。
如果不使用this,那就需要給identify()和speak()顯示傳入一個(gè)上下文對(duì)象。

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)雅的方式來隱式傳遞一個(gè)對(duì)象引用,因此可以將API設(shè)計(jì)的更加簡(jiǎn)潔且易于復(fù)用。
當(dāng)你的代碼越來越復(fù)雜的時(shí)候,顯示的傳遞上下文對(duì)象會(huì)變得很混亂。

2. 關(guān)于this的誤解之 誤解之this是指向自身

通常會(huì)將this理解成指向函數(shù)自身。平常我們會(huì)在函數(shù)內(nèi)部調(diào)用自身(例如遞歸)。在JavaScript中函數(shù)也是一個(gè)對(duì)象,那么我們可以在調(diào)用函數(shù)的時(shí)候存儲(chǔ)狀態(tài)(屬性的值)。
我們看下以下代碼,會(huì)發(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ù)自身就是錯(cuò)誤的!
在執(zhí)行foo.count=0的時(shí)候,確實(shí)向函數(shù)對(duì)象foo添加了一個(gè)count屬性,但是函數(shù)內(nèi)部的this.count的this并不是指向那個(gè)函數(shù)對(duì)象(其實(shí)是window對(duì)象)。
那么增加的是哪個(gè)count?這是創(chuàng)建在全局變量的一個(gè)count,值為NaN.

如果要從函數(shù)對(duì)象內(nèi)部引用它自身,那只使用this是不夠的。一般你需要通過一個(gè)指向函數(shù)對(duì)象的詞法標(biāo)識(shí)符來引用。

function foo() {
    foo.count = 4    //foo指向它自身
}
setTimeout(function() {
    //匿名函數(shù)無法指向自身
}, 10)

第一個(gè)函數(shù)被稱為具名函數(shù),在它內(nèi)部可以使用foo來引用自身。但是在第二個(gè)例子中,傳入setTimeout(..)的回調(diào)函數(shù)沒有名稱標(biāo)識(shí)符,因此無法從函數(shù)內(nèi)部引用自身。

還有一種方法是通過強(qiáng)制this指向foo函數(shù)對(duì)象

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)
    }
}

如上,我們強(qiáng)制this指向了foo,這樣就可以獲得我們想要的答案了。

誤解之它的作用域

第二種錯(cuò)誤的理解是this指向函數(shù)的作用域。這個(gè)問題有些復(fù)雜,因?yàn)樵谀撤N情況下它是正確的。
需要明確的是,this在任何情況下都不指向函數(shù)的詞法作用域。在JavaScript內(nèi)部,作用域確實(shí)很像對(duì)象,可見的標(biāo)識(shí)符都是它的屬性。但是作用域?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

以上代碼運(yùn)行是不會(huì)得到你理想的結(jié)果的,因?yàn)槟悴荒苁褂胻his來引用一個(gè)詞法作用域內(nèi)部的東西。

3. this到底是什么

this是在運(yùn)行時(shí)進(jìn)行綁定的,并不是在編寫時(shí)綁定,它的上下文取決于函數(shù)調(diào)用時(shí)的各種條件。this的綁定和函數(shù)聲明的位置沒有任何關(guān)系,取決于函數(shù)的調(diào)用方式。

當(dāng)一個(gè)函數(shù)調(diào)用時(shí),會(huì)創(chuàng)建一個(gè)活動(dòng)記錄(有時(shí)候也稱為執(zhí)行上下文)。這個(gè)記錄 會(huì)包含函數(shù)在哪里被調(diào)用(調(diào)用棧),函數(shù)的調(diào)用方法,傳入的參數(shù)信息。this就是記錄的其中一個(gè)屬性,會(huì)在函數(shù)執(zhí)行的過程中用到。

總結(jié)

這里我們要明白this既不是指向函數(shù)自身,也不是指向函數(shù)的詞法作用域。這是理解this的前提。
this實(shí)際上時(shí)在函數(shù)被調(diào)用時(shí)發(fā)生的綁定,它指向什么完全取決于函數(shù)在哪里被調(diào)用。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/89948.html

相關(guān)文章

  • JavaScriptthis終極理解(2)

    摘要:找到函數(shù)的調(diào)用位置最重要的是要分析調(diào)用棧就是為了到達(dá)當(dāng)前執(zhí)行位置所調(diào)用的所有函數(shù)。顯示綁定我們可以使用函數(shù)的和方法,通過這兩個(gè)方法可以在某個(gè)對(duì)象上強(qiáng)制調(diào)用函數(shù)。 在上一篇我們了解過每個(gè)函數(shù)的this是在調(diào)用的時(shí)候綁定的,完全卻決于函數(shù)的調(diào)用位置(也就是函數(shù)的調(diào)用方法)。 1. 調(diào)用位置 在理解this的綁定過程之前,首先要理解調(diào)用位置:調(diào)用位置就是函數(shù)在代碼中被調(diào)用的位置,而不是聲明的...

    liujs 評(píng)論0 收藏0
  • 筆試題之Event Loop終極

    摘要:下面開始分析開頭的代碼第一輪事件循環(huán)流程整體作為第一個(gè)宏任務(wù)進(jìn)入主線程,遇到,輸出遇到函數(shù)聲明,聲明暫時(shí)不用管遇到,其回調(diào)函數(shù)被分發(fā)到微任務(wù)中。我們記為遇到,其回調(diào)函數(shù)被分發(fā)到宏任務(wù)中。 先上一道常見的筆試題 console.log(1); async function async1() { console.log(2); await async2(); con...

    niceforbear 評(píng)論0 收藏0
  • 面試題之Event Loop終極

    摘要:下面開始分析開頭的代碼第一輪事件循環(huán)流程整體作為第一個(gè)宏任務(wù)進(jìn)入主線程,遇到,輸出遇到函數(shù)聲明,聲明暫時(shí)不用管遇到,其回調(diào)函數(shù)被分發(fā)到微任務(wù)中。我們記為遇到,其回調(diào)函數(shù)被分發(fā)到宏任務(wù)中。 先上一道常見的筆試題 console.log(1); async function async1() { console.log(2); await async2(); con...

    233jl 評(píng)論0 收藏0
  • jsthis的“終極三問”

    摘要:是什么本質(zhì)是一個(gè)綁定,在函數(shù)被調(diào)用時(shí)建立。它的指向是完全由函數(shù)被調(diào)用的調(diào)用點(diǎn)來決定的。因?yàn)楹瘮?shù)的調(diào)用點(diǎn)在全局作用域,所以指向全局變量這里就是函數(shù)的調(diào)用點(diǎn)存在的意義在函數(shù)體內(nèi)部指代函數(shù)當(dāng)前的運(yùn)行環(huán)境。從而實(shí)現(xiàn)干凈的設(shè)計(jì)和更容易的復(fù)用。 this是什么? this 本質(zhì)是一個(gè)綁定, 在函數(shù)被調(diào)用時(shí)建立。它的指向是完全由函數(shù)被調(diào)用的調(diào)用點(diǎn)來決定的。 function baz() { ...

    silvertheo 評(píng)論0 收藏0
  • 終極蛇皮上帝視角之微信小程序之告別 setData

    摘要:而小程序官方的是在中調(diào)用方法來改變數(shù)據(jù),從而改變界面。為了寫測(cè)試讓咱們來重構(gòu)一把,利用學(xué)習(xí)過的函數(shù)式編程中的高階函數(shù)把依賴注入。也就是說當(dāng)中的某個(gè)數(shù)據(jù)更新的時(shí)候,我們并不知道它會(huì)影響哪個(gè)中的屬性,特別的還有依賴于的情況。 眾所周知 Vue 是借助 ES5 的 Object.defineProperty 方法設(shè)置 getter、setter 達(dá)到數(shù)據(jù)驅(qū)動(dòng)界面,當(dāng)然其中還有模板編譯等等其他...

    wuyumin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<