先前寫的那一篇,我已經移到底下了,實際上問題多多,後來經過幾個高手朋友的指教,再次測試之後,才知道造成錯誤的真正原因是和 jQuery 混在一起了吧。
不過我當初在測試時,是有先避開 jQuery 哩?反正我已經無法重現當初的錯誤,只好把問題怪罪給它了。
總之,目前用底下二個方法來處理物件及測試成員函式的呼叫,都沒有問題。
第一種如下。原本紅色那行應該會有問題,但現在測試一切OK。
function obj(){
this.x = 1;
this.func1 = function(){
this.x++;
console.log("func1 : x = " + this.x);
};
this.func2 = function(){
this.x++;
console.log("func2 : x = " + this.x);
this.func1();
};
}
var myobj = new obj();
myobj.func1();
myobj.func2();
第二種方式是直接宣告物件。底下也是OK的。如果把全部的 this 都換成 myobj,也都沒問題。我在網路上查到有人說用 this 會出錯,換成 myobj 才可以。也許這是之前的問題,現在都解決了吧。
var myobj = {
x : 1,
func1 : function(){
this.x++;
console.log("func1 : x = " + this.x);
},
func2 : function(){
this.x++;
console.log("func2 : x = " + this.x);
this.func1();
}
}
myobj.func1();
myobj.func2();
不過,如果搭配 jQuery 使用,在 jQuery 的函式中,就不能直接使用,因為此時的 this 是 jQuery 找到的物件。
底下這樣用會有問題
$("xxx").each(function(){
this.func1(); // 這樣會有問題
});
要改成這樣才行
var self = this; // 先把 this 存起來
$("xxx").each(function(){
self.func1(); // 這樣OK
});
另外學到一件事,用 var 宣告的變數會擴展到整個 function,例如:
var i=3;
for(var i=1; i<10; i++)
{
...
}
console.log(i);
最後的 i 可不是 3 ,而是 10,這件事真的很詭異。
Yap 告知可以用 let 來宣告變數,就可以限制在區塊中,可參考這篇「深入浅出ES6(十四):let和const」。
-- 2017/01/19
底下是昨天寫的,內容有問題,參考就好,留著當紀念。
聽說 JavaScript 的地雷很多,今天終於踩到,幸好爬文半天,終於找到解答。
簡單來說,就是在一個簡單的物件中,某個成員函式呼叫另一個成員函式,想不到那麼簡單直覺的動作,也會出問題。(這些術語或許不適合 JavaScript,看在很少用 JavaScript 的份上,就別計較太多了。)
我的程式原本像這樣:
function obj ()
{
this.func1 = function(){
....
};
this.func2 = function(){
this.func1(); // 錯誤在這裡,
};
}
後來看到有人提出一種解答,就是把 this 換成物件的名稱,如下:
var obj = {
func1 : function(){
....
},
func2 : function(){
obj.func1(); // 這樣就 OK 了
}
}
不過我把我的程式中的 this 換成 obj 也不行。
大概是因為我的 obj 是類似定義成一個類別(函式),之後還會用 var x = new obj(); 的方式去宣告。
而那個解答則是一開始就宣告物件 var obj = xxx,所以才能用 obj.func1() 來執行。
後來又爬文找到另一個解法,就是另外用 prototype 來宣告,如下:
function obj ()
{
this.func1 = function(){
....
};
}
obj.prototype.func2 = function(){
this.func1(); // 這樣就可以了
};
不過事情其實沒那麼簡單,因為我又用了 jQuery,所以還是有問題。
obj.prototype.func2 = function(){
$("xxx").each(function(){
this.func1(); // 還是有問題
});
};
最後才想到,應該是那個 this 已經不是 obj 物件的 this,而是 jQuery 所選到的物件了。所以又改成如下才真正沒問題了。
obj.prototype.func2 = function(){
tmp = this; // 先把 this 存在 tmp 中
$("xxx").each(function(){
tmp.func1(); // OK了
});
};