一個(gè)對(duì)于js this關(guān)鍵字的問題
更新時(shí)間:2007年01月09日 00:00:00 作者:
所以拿出來與大家共勉:
先運(yùn)行以下的js代碼
<script>
foo = {
'bar': function () {
alert(this);
},
'toString': function () {
return 'foo';
}
};
foo.bar();//返回的是"foo"
(foo.bar)();//返回的是"[object Window]"
(foo.bar || null)();//返回的是"[object Window]"
bar = foo.bar; bar();//返回的是"[object Window]"
</script>
我對(duì)這里的代碼的解釋:
foo.bar(); //打印foo
//1. alert隱式調(diào)用toString方法,轉(zhuǎn)型成字符串,在foo里重寫了toString方法,因此為foo
(foo.bar)();//打印foo
//2. 這里的執(zhí)行同上
(foo.bar || null)();
/*
3. 這里在IE6.0,Mozilla Firefox1.5.0.7和Opera9.0里有不同的效果,IE和Opera都是object,Mozilla的為foo
暫且不談這幾個(gè)的JS對(duì)||的解釋方法,這與bar方法中的this還有和||運(yùn)算符是有關(guān)的。經(jīng)過||之后
這里的this已經(jīng)不再為window了,this關(guān)鍵字的作用,如果按照C++的理解,應(yīng)該為動(dòng)態(tài)聯(lián)編,而非靜態(tài)聯(lián)編,我們平常的例子中
<script>
(function (){
this.div = document.createElement("div");div.innerHTML="never-online";
document.body.appendChild(div);
this.div.onclick = function(){
alert(this.tagName);//這里的this就是div而非匿名函數(shù)中的this
}
})()
</script>
也就是說,這里this的作用域不再是foo對(duì)象,而是一個(gè)全局的作用域。因此alert(this)相當(dāng)于alert(window);
所以為object
BTW:有可能是||運(yùn)算符是要把兩個(gè)表達(dá)式的執(zhí)行轉(zhuǎn)換為全局范圍的比較,所以在IE和Opera中,這里(foo.bar || null)返回的是一個(gè)全局引用,即:
'bar': function () {
alert(this);//這里的this已經(jīng)為全局this,全局的this,即為window
},
詳細(xì)的,我將在篇末加入一段代碼,以示說明
*/
bar = foo.bar; bar();//返回的是"[object Window]"
/*4.
這里在IE6.0,Mozilla Firefox1.5.0.7和Opera9.0里都為相同的object,如果理解上面的執(zhí)行,理解這句顯然會(huì)比較簡(jiǎn)單
理由同上,這里把foo.bar的引用給到一個(gè)全局變量bar,而全局變量都隸屬于window的引用,看下面代碼:
var a = 'never-online';
alert(this.a); //never-online
alert(window.a); //never-online
如果你嘗試著把bar = foo.bar; bar();改成以下代碼,或許就可以明白了
foo.alert = foo.bar; foo.alert ();
這里的foo.alert依然為foo對(duì)象的引用,因此foo對(duì)象里的this,在這里依然有效,并沒有成為window object
因?yàn)楹苊黠@的bar屬性window,因此引用foo.bar里雖然有this,但是this引用為window
*/
再看看我們把這個(gè)例子改成這樣:
<script>
foo = {
'bar': function () {
var oSelf = this;
alert(this.toString);
if (oSelf==window) {
oSelf = foo;
}
alert(oSelf);
},
'toString': function () {
return 'foo';
}
};
window.toString = function () {
alert("引用全局this --- window");
}
foo.bar();
(foo.bar)();
(foo.bar || null)();
bar = foo.bar; bar();
</script>
這樣應(yīng)該明白原因了。
從這個(gè)例中(foo.bar || null)(); 可以看出Mozilla的解釋器會(huì)更“標(biāo)準(zhǔn)”一些,而Opera和IE的解釋方法則與Mozilla的不一樣。||運(yùn)算符的作用,出現(xiàn)了不同的效果。同我上面所說的, 有可能是||運(yùn)算符是要把兩個(gè)表達(dá)式的執(zhí)行轉(zhuǎn)換為全局范圍的比較,所以在IE和Opera中,這里(foo.bar || null)返回的是一個(gè)全局引用
先運(yùn)行以下的js代碼
<script>
foo = {
'bar': function () {
alert(this);
},
'toString': function () {
return 'foo';
}
};
foo.bar();//返回的是"foo"
(foo.bar)();//返回的是"[object Window]"
(foo.bar || null)();//返回的是"[object Window]"
bar = foo.bar; bar();//返回的是"[object Window]"
</script>
我對(duì)這里的代碼的解釋:
foo.bar(); //打印foo
//1. alert隱式調(diào)用toString方法,轉(zhuǎn)型成字符串,在foo里重寫了toString方法,因此為foo
(foo.bar)();//打印foo
//2. 這里的執(zhí)行同上
(foo.bar || null)();
/*
3. 這里在IE6.0,Mozilla Firefox1.5.0.7和Opera9.0里有不同的效果,IE和Opera都是object,Mozilla的為foo
暫且不談這幾個(gè)的JS對(duì)||的解釋方法,這與bar方法中的this還有和||運(yùn)算符是有關(guān)的。經(jīng)過||之后
這里的this已經(jīng)不再為window了,this關(guān)鍵字的作用,如果按照C++的理解,應(yīng)該為動(dòng)態(tài)聯(lián)編,而非靜態(tài)聯(lián)編,我們平常的例子中
<script>
(function (){
this.div = document.createElement("div");div.innerHTML="never-online";
document.body.appendChild(div);
this.div.onclick = function(){
alert(this.tagName);//這里的this就是div而非匿名函數(shù)中的this
}
})()
</script>
也就是說,這里this的作用域不再是foo對(duì)象,而是一個(gè)全局的作用域。因此alert(this)相當(dāng)于alert(window);
所以為object
BTW:有可能是||運(yùn)算符是要把兩個(gè)表達(dá)式的執(zhí)行轉(zhuǎn)換為全局范圍的比較,所以在IE和Opera中,這里(foo.bar || null)返回的是一個(gè)全局引用,即:
'bar': function () {
alert(this);//這里的this已經(jīng)為全局this,全局的this,即為window
},
詳細(xì)的,我將在篇末加入一段代碼,以示說明
*/
bar = foo.bar; bar();//返回的是"[object Window]"
/*4.
這里在IE6.0,Mozilla Firefox1.5.0.7和Opera9.0里都為相同的object,如果理解上面的執(zhí)行,理解這句顯然會(huì)比較簡(jiǎn)單
理由同上,這里把foo.bar的引用給到一個(gè)全局變量bar,而全局變量都隸屬于window的引用,看下面代碼:
var a = 'never-online';
alert(this.a); //never-online
alert(window.a); //never-online
如果你嘗試著把bar = foo.bar; bar();改成以下代碼,或許就可以明白了
foo.alert = foo.bar; foo.alert ();
這里的foo.alert依然為foo對(duì)象的引用,因此foo對(duì)象里的this,在這里依然有效,并沒有成為window object
因?yàn)楹苊黠@的bar屬性window,因此引用foo.bar里雖然有this,但是this引用為window
*/
再看看我們把這個(gè)例子改成這樣:
<script>
foo = {
'bar': function () {
var oSelf = this;
alert(this.toString);
if (oSelf==window) {
oSelf = foo;
}
alert(oSelf);
},
'toString': function () {
return 'foo';
}
};
window.toString = function () {
alert("引用全局this --- window");
}
foo.bar();
(foo.bar)();
(foo.bar || null)();
bar = foo.bar; bar();
</script>
這樣應(yīng)該明白原因了。
從這個(gè)例中(foo.bar || null)(); 可以看出Mozilla的解釋器會(huì)更“標(biāo)準(zhǔn)”一些,而Opera和IE的解釋方法則與Mozilla的不一樣。||運(yùn)算符的作用,出現(xiàn)了不同的效果。同我上面所說的, 有可能是||運(yùn)算符是要把兩個(gè)表達(dá)式的執(zhí)行轉(zhuǎn)換為全局范圍的比較,所以在IE和Opera中,這里(foo.bar || null)返回的是一個(gè)全局引用
相關(guān)文章
js setTimeout()函數(shù)介紹及應(yīng)用以倒計(jì)時(shí)為例
setTimeout() 方法用于在指定的毫秒數(shù)后調(diào)用函數(shù)或計(jì)算表達(dá)式,下面有個(gè)倒計(jì)時(shí)的示例,需要的朋友可以學(xué)習(xí)下2013-12-12
bootstrap-table實(shí)現(xiàn)服務(wù)器分頁的示例 (spring 后臺(tái))
本篇文章主要介紹了bootstrap-table實(shí)現(xiàn)服務(wù)器分頁的示例 (spring 后臺(tái)),具有一定的參考價(jià)值,有興趣的可以了解一下2017-09-09
比較簡(jiǎn)單實(shí)用的使用正則三種版本的js去空格處理方法
比較簡(jiǎn)單實(shí)用的使用正則三種版本的js去空格處理方法...2007-11-11
30個(gè)高逼格代碼的JavaScript高級(jí)單行代碼
這篇文章中列出了一個(gè)系列的 30 個(gè) JavaScript 單行代碼,它們?cè)谑褂?nbsp;vanilla js(≥ ES6)進(jìn)行開發(fā)時(shí)非常有用,它們也是使用該語言在最新版本中為我們提供的所有功能來解決問題的優(yōu)雅方式,將它們分為以下5大類:日期、字符串、數(shù)字、數(shù)組、工具2023-08-08
Javascript動(dòng)態(tài)伸縮+淡出淡入
一種不錯(cuò)代碼應(yīng)用實(shí)例,大家可以根據(jù)這個(gè)代碼,拓寬出更好的代碼2009-02-02
JavaScript中的this原理及6種常見使用場(chǎng)景詳解
這篇文章主要介紹了JavaScript中的this原理及6種常見使用場(chǎng)景詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02

