this到底指向哪里


this指向調用它的對象

首先要明確,this指向調用方,誰調用,this指向誰。

直接調用

舉個栗子:

var 
    test = 'window'
;
function testThis () {
    var test = 'inner';
    this.test = 'test change';
    console.log(this.test)
}
testThis(); // test change
console.log(window.test) // test change

在chrome中執行后可以發現,外部掛在window下的test被修改了,因為這個testThis的函數,是被window調用的,它只會讀取window下的test。

構造函數調用

再舉個栗子:

var 
    test = 'window'
;
function testThis () {
    var test = 'inner';
    console.log(this.test)
    this.test = 'test change';
    console.log(this.test)
}
var newTestThis = new testThis(); 
// undefined
// test change
console.log(window.test) // window

在chrome中執行以下可以發現,依次輸出undefined、test change、window。
這個栗子與上面的區別在於調用了new。此時,該函數作為構造函數調用,我們都知道,構造函數中的this都指向new出來的對象。所以this指向了這個新生成的newTestThis。自然地,window下test就沒有被修改。

嵌套調用

接下來舉一個栗子,來說明在函數嵌套調用時的this指向:

var x = 'global'
function testThis () {
	// this.x = 'fuck';
	// console.log(this)
	console.log(this.x)
}
function innerObj () {
	this.x = 'inner';
	testThis();
	this.innerTestThis = testThis;
	this.innerTestThis();
}

function wrapObj () {
	this.x = 'wrap';
	// var test = new testThis();
	// console.log(test.x)
	testThis();

	this.wrapTestThis = testThis;
	this.wrapTestThis();

	this.innerTestThis = new innerObj();
}
var wrap = new wrapObj();
wrapObj();
// global
// wrap
// global
// inner
// wrap
// wrap
// wrap
// inner

很明顯,在函數嵌套時,如果不給函數指定調用對象,則不論被調用函數是在哪個函數的作用域里,被調用的函數的this都是指向window的。
我們可以這樣理解,在直接調用時,這些函數除了擁有自己的作用域外,就像是把這幾行代碼寫到了相應的位置。可以想一下,所有的js代碼最后都拼到一起,很明顯,他們的調用方都是window。

總結一下:1.不論函數在哪里被調用,只要沒有指定調用方,則this都指向window。指定了調用方,就指向調用方。2.作為構造函數中調用,this指向新生成的對象。

分析一下:setTimeout和setInterval

bind的作用就是給函數一個指定的thisArg,經常使用bind的地方就是setTimeout和setInterval了。為什么呢?
setTimeout和setInterval都有一個特點,它會將回調函數的作用域轉移到window上面。其實結合我們上面說的,很容易知道為什么。
以setTimeout為例:翻看MDN下setTimeout的定義,可以發現,setTimeout是把一段callback代碼延遲執行。寫過callback的同學都知道,callback的代碼其實就是占了位,然后去調用一行行的代碼,所以,callback中的this也會指向window。
實際開發中,我們不希望this指向window,故而常使用bind來使this指向我們希望的對象。

bind、apply、call

說到了bind,就還需要提一下另外的可以改變this指向的方法:apply和call。
這兩個函數大同小異,只是傳參有區別。不論使用apply還是call,都會傳入一個thisArg,作為函數調用方,讓函數中的this指向thisArg。
在下一篇,我會介紹一下apply和call。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM