溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

JavaScript中this對(duì)象是什么

發(fā)布時(shí)間:2020-12-08 14:00:50 來源:億速云 閱讀:110 作者:小新 欄目:web開發(fā)

小編給大家分享一下JavaScript中this對(duì)象是什么,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

前言:最近在細(xì)讀Javascript高級(jí)程序設(shè)計(jì),對(duì)于我而言,中文版,書中很多地方翻譯的差強(qiáng)人意,所以用自己所理解的,嘗試解讀下。如有紕漏或錯(cuò)誤,會(huì)非常感謝您的指出。文中絕大部分內(nèi)容引用自《JavaScript高級(jí)程序設(shè)計(jì)第三版》。

this對(duì)象是在運(yùn)行時(shí)基于函數(shù)的執(zhí)行環(huán)境綁定:

在全局環(huán)境中, this等于window,而當(dāng)函數(shù)被作為某個(gè)對(duì)象的方法調(diào)用時(shí),this就指向了那個(gè)對(duì)象。

不過匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其this對(duì)象通常指向window。

在閉包中使用this對(duì)象可能會(huì)導(dǎo)致一些問題。

有時(shí)候由于編寫閉包的方式不同,這一點(diǎn)可能不會(huì)那么明顯。

// 在全局環(huán)境中,this等于window
function thisBoundForWindow(){
    console.log(this);
    console.log(this.name);
}
thisBoundForWindow(); // Window
var o = new Object();
o.name = "Shaw";
//當(dāng)函數(shù)被作為某個(gè)對(duì)象的方法調(diào)用時(shí),this就指向了那個(gè)對(duì)象。
thisBoundForWindow.apply(o); // {name: "Shaw"}; "Shaw" ;
//在閉包中使用this對(duì)象可能會(huì)導(dǎo)致一些問題。
//有時(shí)候由于編寫閉包的方式不同,這一點(diǎn)可能不會(huì)那么明顯。
var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function() {
        return function() {
            console.log(this.name);
        }
    }
}
object.getNameFunc()(); // "The Window"
/*
object.getNameFunc return=> function() {
        return function() {
            console.log(this.name);
        }
    }  => ()調(diào)用,還是在全局環(huán)境下調(diào)用的,所以this.name = window.name => "The Window"
*/

以上代碼先創(chuàng)建了一個(gè)全局變量name,又創(chuàng)建了一個(gè)包含name屬性的對(duì)象。

這個(gè)對(duì)象還包含一個(gè)方法——getNameFunc(), 它返回一個(gè)匿名函數(shù),而匿名函數(shù)又返回this.name,這個(gè)匿名函數(shù)就是閉包。

再來回顧一下“閉包”的定義:

有權(quán)訪問另外一個(gè)作用域中的變量的函數(shù)就是閉包。

由于getNameFunc()返回一個(gè)函數(shù),因此調(diào)用object.getNameFunc()()就會(huì)調(diào)用它返回的函數(shù),結(jié)果就是控制臺(tái)打印出一個(gè)字符竄。

然而,這個(gè)例子返回的字符竄是"The Window",即全局name變量的值。

那么,如何把this指向例子中的object呢?

把外部作用域的this對(duì)象保存在一個(gè)閉包能夠訪問到的變量里,就可以讓閉包訪問該對(duì)象了。(注意,這種手法,在使用回調(diào)函數(shù)的時(shí)候也經(jīng)常用到)。

var name = "The Window";
var object = {
    name: "My Object",
    getNameFunc: function(){
        var that = this;
        return function() {
            console.log(that.name);
        }
    }
}
object.getNameFunc()(); // "My Object"
/*
// 偽代碼過程
object.getNameFunc  execute
=> this = object = that 
=>function() {console.log(that.name);}  
=> ()
=> that.name = object.name 
=> "My Object" 
*/

在定義匿名函數(shù)之前,把this對(duì)象賦值給了一個(gè)名叫that的變量。

而在定義了閉包之后,閉包也可以訪問這個(gè)變量,因?yàn)樗俏覀冊(cè)诎瘮?shù)中特意聲明的一個(gè)變量。

即使在函數(shù)返回之后,that也仍然引用著object, 所以調(diào)用Object.getNameFunc()就返回了"My Object"。

在幾種特殊情況下,this的值可能會(huì)意外地改變。比如,下面的代碼時(shí)修改前面例子的結(jié)果。

var name = "The Window";
var object = {
    name: "My Object",
    getName: function() {
        console.log(this.name);
    }
};
object.getName(); // "My Object"
(object.getName)(); // "My Object"
(object.getName = object.getName)(); // "The Window"

第一行代碼跟平常一樣調(diào)用了object.getName(),返回時(shí)"My Object",因?yàn)閠his.name就是object.name。

第二行代碼在調(diào)用這個(gè)方法前給它加上了括號(hào),雖然加上括號(hào)之后,就好像是在引用一個(gè)函數(shù),但this的值得到了維持,因?yàn)閛bject.getName和(object.getName)的定義是相同的。

第三行代碼先執(zhí)行了一條賦值語句,然后再調(diào)用賦值后的結(jié)果。因?yàn)檫@個(gè)賦值表達(dá)式是函數(shù)本身,所以this的值得不到維持,結(jié)果就返回了"The Window"。

//第三個(gè)例子偽代碼
//理解此段代碼,首先要明確一個(gè)知識(shí)點(diǎn):賦值語句是有返回值的,返回值就是所賦的值(也就是‘=’右邊的值)。

(object.getName = object.getName)(); // "The Window"

(object.getName = function(){ console.log(this.name)})();

(function(){console.log(this.name)})();
//所以this指向window

當(dāng)然,我們不太可能會(huì)像第二行和第三行代碼一樣調(diào)用這個(gè)方法。暫時(shí)理解不了也沒事,這個(gè)例子有助于說明即使是語法的細(xì)微變化,都有可能意外地改變this值。

看完了這篇文章,相信你對(duì)JavaScript中this對(duì)象是什么有了一定的了解,想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細(xì)節(jié)

免責(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)容。

AI