小編給大家分享一下JavaScript中this對象是什么,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!
成都創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務領(lǐng)域包括:成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營銷網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務,滿足客戶于互聯(lián)網(wǎng)時代的崇左網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!
前言:最近在細讀Javascript高級程序設(shè)計,對于我而言,中文版,書中很多地方翻譯的差強人意,所以用自己所理解的,嘗試解讀下。如有紕漏或錯誤,會非常感謝您的指出。文中絕大部分內(nèi)容引用自《JavaScript高級程序設(shè)計第三版》。
this對象是在運行時基于函數(shù)的執(zhí)行環(huán)境綁定:
在全局環(huán)境中, this等于window,而當函數(shù)被作為某個對象的方法調(diào)用時,this就指向了那個對象。
不過匿名函數(shù)的執(zhí)行環(huán)境具有全局性,因此其this對象通常指向window。
在閉包中使用this對象可能會導致一些問題。
有時候由于編寫閉包的方式不同,這一點可能不會那么明顯。
// 在全局環(huán)境中,this等于window function thisBoundForWindow(){ console.log(this); console.log(this.name); } thisBoundForWindow(); // Window var o = new Object(); o.name = "Shaw"; //當函數(shù)被作為某個對象的方法調(diào)用時,this就指向了那個對象。 thisBoundForWindow.apply(o); // {name: "Shaw"}; "Shaw" ;
//在閉包中使用this對象可能會導致一些問題。 //有時候由于編寫閉包的方式不同,這一點可能不會那么明顯。 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)建了一個全局變量name,又創(chuàng)建了一個包含name屬性的對象。
這個對象還包含一個方法——getNameFunc(), 它返回一個匿名函數(shù),而匿名函數(shù)又返回this.name,這個匿名函數(shù)就是閉包。
再來回顧一下“閉包”的定義:
有權(quán)訪問另外一個作用域中的變量的函數(shù)就是閉包。
由于getNameFunc()返回一個函數(shù),因此調(diào)用object.getNameFunc()()就會調(diào)用它返回的函數(shù),結(jié)果就是控制臺打印出一個字符竄。
然而,這個例子返回的字符竄是"The Window",即全局name變量的值。
那么,如何把this指向例子中的object呢?
把外部作用域的this對象保存在一個閉包能夠訪問到的變量里,就可以讓閉包訪問該對象了。(注意,這種手法,在使用回調(diào)函數(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對象賦值給了一個名叫that的變量。
而在定義了閉包之后,閉包也可以訪問這個變量,因為它是我們在包含函數(shù)中特意聲明的一個變量。
即使在函數(shù)返回之后,that也仍然引用著object, 所以調(diào)用Object.getNameFunc()就返回了"My Object"。
在幾種特殊情況下,this的值可能會意外地改變。比如,下面的代碼時修改前面例子的結(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(),返回時"My Object",因為this.name就是object.name。
第二行代碼在調(diào)用這個方法前給它加上了括號,雖然加上括號之后,就好像是在引用一個函數(shù),但this的值得到了維持,因為object.getName和(object.getName)的定義是相同的。
第三行代碼先執(zhí)行了一條賦值語句,然后再調(diào)用賦值后的結(jié)果。因為這個賦值表達式是函數(shù)本身,所以this的值得不到維持,結(jié)果就返回了"The Window"。
//第三個例子偽代碼 //理解此段代碼,首先要明確一個知識點:賦值語句是有返回值的,返回值就是所賦的值(也就是‘=’右邊的值)。 (object.getName = object.getName)(); // "The Window" (object.getName = function(){ console.log(this.name)})(); (function(){console.log(this.name)})(); //所以this指向window
當然,我們不太可能會像第二行和第三行代碼一樣調(diào)用這個方法。暫時理解不了也沒事,這個例子有助于說明即使是語法的細微變化,都有可能意外地改變this值。
看完了這篇文章,相信你對JavaScript中this對象是什么有了一定的了解,想了解更多相關(guān)知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,感謝各位的閱讀!