iT邦幫忙

0

在物件中 this 的值?

var user = {
	count: 1,
	getCount: function(){
		return this.count;
	}.bind(this)
};

user.getCount();	//undefined

原本預期 bind 中的 this 應該是指向物件,結果卻是指向 windows ,為何會這樣呢?

小魚 iT邦高手 1 級 ‧ 2019-07-22 14:01:42 檢舉
JavaScript的this博大精深...
cn41408 iT邦新手 5 級 ‧ 2019-07-23 09:35:44 檢舉
建議應該要先判斷你的this在哪裡
4
fillano
iT邦超人 1 級 ‧ 2019-07-22 14:17:57
最佳解答

你要知道Javascript怎麼執行的。

var user = {
	count: 1,
	getCount: function(){
		return this.count;
	}.bind(this)
};

這個例子中,getCount:之後的expression是在var user同樣的context中跑,跑完才把結果assign給getCount。在這個context中執行bind(this),就看執行當下的this是什麼。如果是在global context跑,那就是window物件。

看更多先前的回應...收起先前的回應...
fillano iT邦超人 1 級 ‧ 2019-07-22 14:21:52 檢舉

這樣會跑出1:

function A() {
	this.count = 1;
	var inner = {
		getCount: function() {
			console.log(this.count);
		}.bind(this)
	};
	//會bind到constructor執行當下的this,也就是A產生的實例
	this.togo = function() {
		inner.getCount();
	}
}
var a = new A;
a.togo();
Liuqadnyc iT邦新手 5 級 ‧ 2019-07-22 15:14:08 檢舉

這個我明白,因為 new 會讓 this 指向新建構的物件,所以 bind 中的 this 會指向 a ,而 a 的 count 就是 1 。可是為何

var user = {
	count: 1,
	getCount: function(){
		return this.count;
	}.bind(this)
};

中的return this.count的 this 會指向 user ,而 bind 中的 this 卻是指向 window ?

fillano iT邦超人 1 級 ‧ 2019-07-22 15:24:51 檢舉

我不是說過

function(){
	return this.count;
}.bind(this)

這個expression跑的時候,this是指向window嗎?假設var user是在global context跑的話。

fillano iT邦超人 1 級 ‧ 2019-07-22 15:28:34 檢舉

Javascript的this,基本上是runtime決定的。所以function裡面的this,會到執行的時候決定。但是問題是跑bind的時候,他是在global context下,這時的this是window。然後你的function就被綁住,this永遠是window。即使你跑user.getCount()也一樣。

Liuqadnyc iT邦新手 5 級 ‧ 2019-07-22 16:07:15 檢舉

所以物件中不是新的 context ,只有在 function 才是新的 context ,因此 bind 中的 this 取決於你在哪裡執行,是這個意思嗎?

fillano iT邦超人 1 級 ‧ 2019-07-22 18:30:16 檢舉

不是。

先不管function expression裡面的this,因為他是function執行實才會決定。你的function expression是:function(){...}.bind(this),以你的例子,上述expression是在global context執行的,所以bind傳進來的this是window物件。然後你定義的function,this就被綁在window物件不會改變,然後這個bound function就指派給user物件的getCount屬性。

執行user.getCount()時,因為他已經被綁在window物件,如果window物件沒有count屬性(或是沒有count這個global變數,在global context這兩件事是相等的),結果就是undefined。

關鍵是function(){...}.bind(this)這個expression在哪個context執行。

Javascript只有三種Context:global, function, eval,並沒有物件的context這種東西。

Liuqadnyc iT邦新手 5 級 ‧ 2019-07-22 20:28:27 檢舉

恩恩我了解了,之前沒有context的概念,謝謝大大 :D

我的兩個this不一樣就是因為一個是在 global context ,另一個在 function context 。

1
dragonH
iT邦大師 1 級 ‧ 2019-07-22 13:46:48

codepen

const user = {
	count: 1,
	getCount() {
		return this.count;
	}
};
console.log(user.getCount())

參考1

參考2

參考3

看更多先前的回應...收起先前的回應...
Liuqadnyc iT邦新手 5 級 ‧ 2019-07-22 13:54:07 檢舉

我使用bind是因為要讓 func() 得到 1 而不是 undefined

var func = user.getCount;
func();

這個地方加bind有種畫蛇添足的感覺

Liuqadnyc iT邦新手 5 級 ‧ 2019-07-22 20:24:03 檢舉

不然你要如何 pass function 而不會得到 undefined 呢?

dragonH大 有說了啊

var user = {
	count: 1,
	getCount: function() {
		return this.count;
	}
};
var func = user.getCount();
func; //1
dragonH iT邦大師 1 級 ‧ 2019-07-23 09:00:41 檢舉

沒喔

他要的效果我上面的做不到

請看 fillano大 的答案比較詳細

0
浩瀚星空
iT邦大師 1 級 ‧ 2019-07-22 17:40:38

this在javascript中,你永遠都不能將其當成變數來使用的。
真要說的話。它算是特殊應用式。

fillano大有跟你說很多了。所以你要能理解。

一般如果有跨區域的情況下,我都會用一個變數來處理。不會直接使用this。
this就多就是同領域下的情況下才會使用。

畢竟上面就有人說了。this是一件很博大精深的事。

認真來說,其實所有的語言都有this的應用方式。其道理都是一樣的東西。
只是javascript的變數領域比較奇特。

Liuqadnyc iT邦新手 5 級 ‧ 2019-07-22 20:31:22 檢舉

是阿,我最後就用bind(user)解決,但還是想了解背後原因。

原因???
fillano大不是跟你說明完了?

this並不是一種變數的型態存在。真正要說的話,它比較算是一種指向的存在。

也就是說,在不同的區域它的指向值是不一樣的。

我要發表回答

立即登入回答