var Obj=function(msg){
this.msg=msg;
this.shout=function()
{
alert(this.msg);
};
this.waitAndShout=function()
{
setTimeout(this.shout, 2000);
};
};
var aa=new Obj("abc");
aa.waitAndShout();
上述是某個javascript面試的題目,debug後發現,只要在this.shout後面加上()即可正常,
我的問題是【為什麼要加上小括號】,shout才抓的到msg這個變數?
感謝
如果你是這樣子改, 那你就改錯了:
<pre class="c" name="code">
var Obj=function(msg){
this.msg=msg;
this.shout=function()
{
alert(this.msg);
};
this.waitAndShout=function()
{
setTimeout(this.shout(), 2000);
};
};
var aa=new Obj("abc");
aa.waitAndShout();
就這題目而言, 應該是要等待兩秒後才顯示訊息
上面的改法會直接顯示, 不會等待兩秒
要修正的話應該這麼改:
<pre class="c" name="code">
var Obj=function(msg){
this.msg=msg;
this.shout=function()
{
alert(this.msg);
};
this.waitAndShout=function()
{
var _this = this;
setTimeout(function(){_this.shout();}, 2000);
};
};
var aa=new Obj("abc");
aa.waitAndShout();
這題目關鍵的地方在於 js 對於 this 的判定方式, 是單純看 . 號左邊是誰
所以你把 this.shout 丟進 setTimeout 裡面以後, shout 這個 function 裡面的 this 就不是 var Obj 了
你可以這樣子觀察 this:
<pre class="c" name="code">
var Obj=function(msg){
this.msg=msg;
this.shout=function()
{
alert(this);
};
this.waitAndShout=function()
{
setTimeout(this.shout, 2000);
};
};
var aa=new Obj("abc");
aa.waitAndShout();
在我的瀏覽器, 它顯示 this 是 Window 這個物件
而理所當然的 Window 並沒有 .msg 這個屬性, 所以顯示 undefined
可以將setTimeout用function包起來看,很明顯如果用this它將呼叫本身function,不是外部Obj物件,所以需將this儲存在Obj物件的變數裡,在由這變數呼叫function
<pre class="c" name="code">
var Obj=function(msg){
this.msg=msg;
this.shout=function(){
alert(this.msg);
};
this.waitAndShout=function(){
pthis = this;
setTimeout(function(){
pthis.shout();
}, 2000);
};
};
var aa=new Obj("abc");
aa.waitAndShout();