js中的this原理

this的定義

this指的是函數(shù)運(yùn)行時所在的環(huán)境。(不是定義時所在的環(huán)境)

怎么理解這句話呢?看如下例子:

var w = 1;
var wFunction=function(){
    console.log(this.w)
}

var wObj = {
    w:2,
    wFunction:wFunction
}

wFunction()//1
wObj.wFunction()//2

在這個例子中,首先第一個輸出,因為wFunction是運(yùn)行在全局環(huán)境中,所以this指向全局環(huán)境,所以輸出1;第二個輸出,因為wFunction運(yùn)行在wObj環(huán)境中,所以this指向wObj,而wObj的w屬性值為2,所以輸出2;

那么問題來了,為什么第二個說是在wObj環(huán)境中運(yùn)行呢,運(yùn)行環(huán)境是怎么來判別的呢?這得從內(nèi)存的數(shù)據(jù)結(jié)構(gòu)說起。

內(nèi)存的數(shù)據(jù)結(jié)構(gòu)

首先,是考慮到內(nèi)存的數(shù)據(jù)結(jié)構(gòu),才設(shè)計這個this的。那內(nèi)存的數(shù)據(jù)結(jié)構(gòu)是怎樣的呢,先看個例子:

var wObj = {
    w:5
}

console.log(wObj.w)//5

這里,javaScript引擎會在內(nèi)存里先生成一個對象{w:5},然后把這個對象的內(nèi)存地址(reference)賦值給wObj變量。

如果通過wObj.w來讀取這個對象的屬性w,則引擎會先從wObj這個變量拿到對象的內(nèi)存地址,然后從該地址讀出這個對象,返回w屬性。

在看下面一個例子:

var wFunction = function(){
    ...
}
var wObj = {
    wFunc:wFunction
}

console.log(wObj.wFunc())

這里,javaScript引擎會先將函數(shù)function(){...}單獨(dú)保存在內(nèi)存中。然后javaScript引擎會在內(nèi)存里生成一個對象{wFunc:wFunction},而wFunction則是函數(shù)的內(nèi)存地址(reference)。然后把這個對象的內(nèi)存地址賦值給wObj變量。

如果通過wObj.wFunc()執(zhí)行函數(shù),則引擎會先從wObj這個變量拿到對象的內(nèi)存地址,然后從該地址讀出這個對象,返回wFunc屬性,而wFunc屬性的值是函數(shù)function(){...}的內(nèi)存地址(reference),因為這個是單獨(dú)的一個值,所以可以在不同環(huán)境(上下文)執(zhí)行。在這里函數(shù)是通過wObj找到的(wObj的屬性wFunc),所以在wObj環(huán)境中執(zhí)行的。

這里解釋了為啥函數(shù)是可以在不同的環(huán)境中執(zhí)行。那么問題來了,這動態(tài)的執(zhí)行環(huán)境,怎么獲取呢?

this設(shè)計機(jī)制

針對獲取執(zhí)行環(huán)境問題,this就這么設(shè)計出來了,它的設(shè)計目的就是在函數(shù)體內(nèi)部,指代函數(shù)當(dāng)前的運(yùn)行環(huán)境。

回到文章開頭例子,并加以深化如下:

var w = 1;
var wFunction=function(){
    console.log(this.w)
}

var wObj = {
    w:2,
    wFunction:wFunction
}

wFunction()//1
wObj.wFunction()//2

let wObjFunc = wObj.wFunction;
wObjFunc()//1

第一個輸出,函數(shù)執(zhí)行時,是通過全局變量wFunction找到函數(shù)引用地址的,它的執(zhí)行環(huán)境則是全局,因此輸出全局w,為1;

第二個輸出,函數(shù)執(zhí)行時,是通過wObj指向的對象里的wFunction屬性找到的函數(shù)引用地址的,因此,它的執(zhí)行環(huán)境則是wObj指向的對象,因此輸出對象的w,為2;

第三個輸出,函數(shù)執(zhí)行時,是通過全局變量wObjFunc找到函數(shù)引用地址的,(因為let wObjFunc = wObj.wFunction;這直接把函數(shù)的引用地址直接賦給了全局變量wObjFunc,所以wObjFunc直接指向函數(shù)本身)它的執(zhí)行環(huán)境則是全局,因此輸出全局w,為1;

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容