2011-05-02 22 views
6

我正在使用jQuery並嘗試將一些基本的Javascript OOP原則應用於控制懸停行爲的一組函數。但是,我無法弄清楚如何讓「this」關鍵字引用我創建的對象的實例。我的示例代碼是:使用面向對象的jQuery

var zoomin = new Object(); 

zoomin = function() { 
     // Constructor goes here 
}; 

zoomin.prototype = { 
     hoverOn: function() { 
      this.hoverReset(); 
      // More logic here using jQuery's $(this)... 
     }, 
     hoverReset: function() { 
      // Some logic here. 
     } 
     }; 

// Create new instance of zoomin and apply event handler to matching classes. 
var my_zoomin = new zoomin(); 
$(".some_class").hover(my_zoomin.hoverOn, function() { return null; }); 

在上述代碼中的問題的行是調用「this.hoverReset()」的hoverOn內部()函數。由於「this」現在指的是被擱置的元素,因此它不能按預期工作。我基本上喜歡爲該對象的實例(my_zoomin)調用函數hoverReset()。

有沒有辦法做到這一點?

謝謝!

回答

8

僅將函數分配給對象的屬性不會將函數內的this與對象關聯。這是你如何調用函數的方式。

通過調用

.hover(my_zoomin.hoverOn,...) 

你只傳遞功能。它不會「記住」它屬於哪個對象。你可以做的是通過一個匿名函數,並調用hoverOn內:

.hover(function(){ my_zoomin.hoverOn(); },...) 

這將使thishoverOn參考my_zoomin。所以致電this.hoverReset()將工作。但是,在hoverOn裏面,你會而不是有一個對由選擇器創建的jQuery對象的引用。

一個解決辦法是通過選定的元素作爲參數:

var zoomin = function() { 
    // Constructor goes here 
}; 

zoomin.prototype = { 
    hoverOn: function($ele) { 
     this.hoverReset($ele); 
     // More logic here using jQuery's $ele... 
    }, 
    hoverReset: function($ele) { 
     // Some logic here. 
    } 
}; 


var my_zoomin = new zoomin(); 
$(".some_class").hover(function() { 
    my_zoomin.hoverOn($(this)); // pass $(this) to the method 
}, function() { 
    return null; 
}); 

作爲下一個步驟,你可以考慮做一個jQuery plugin

+0

+1對於很好的解釋 – rzetterberg 2011-05-02 01:14:31

+0

謝謝你的出色答案。它確實爲我澄清了一些事情:-)我一定會考慮將它變成一個插件。 – Ralph 2011-05-02 01:28:51

0
  1. 您可以「綁定」的事件處理程序到對象(see Mootools bind code例如)。
  2. 您可以通過對象在匿名函數中的參數和使用,而不是this在事件處理程序

至於1,你bind方法添加到function

bind: function(bind){ 
     var self = this, 
      args = (arguments.length > 1) ? Array.slice(arguments, 1) : null; 

     return function(){ 
      if (!args && !arguments.length) return self.call(bind); 
      if (args && arguments.length) return self.apply(bind, args.concat(Array.from(arguments))); 
      return self.apply(bind, args || arguments); 
     }; 
    } 

不當然,它會與JQ的東西交互。

0

請參閱我的這些問題的答案:

where is my "this"?

why is "this" not this?

this混亂來了所有的時間。

當你將一個函數作爲回調函數傳遞時,它被作爲一個獨立的函數調用,所以它的「this」成爲全局對象。

「綁定」是ecmascript 5的本地部分,並且是函數原型的一部分。如果你到那裏結束我的第二個回答,你會得到一個鏈接到mozilla網站,它有一個bind功能的「兼容性」版本。使用use myfunction.bind(myobject),如果可用,它將使用本機函數,如果不是,則使用JS函數。