JavaScript 物件中成員函式呼叫成員函式

先前寫的那一篇,我已經移到底下了,實際上問題多多,後來經過幾個高手朋友的指教,再次測試之後,才知道造成錯誤的真正原因是和 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了
  });
};

重要度:
文章分類:
電腦標籤:

發表新回應

借我放一下廣告