2009-07-08 38 views
16

我試圖讓我直接在腦海中做jQuery風格的函數鏈接的原則。我的意思是:基本對象/函數鏈接如何在JavaScript中工作?

var e = f1('test').f2().f3(); 

我已經得到了一個例子工作,而另一個沒有。我會在後面發表。我總是想學習如何工作的第一個原則基礎,以便我可以在此基礎上進行構建。到目前爲止,我只是粗略和寬鬆地理解鏈接是如何工作的,而且我遇到了無法智能排除故障的錯誤。

我所知道的:

  1. 函數必須返回自己,又名 「返回此;」可連接函數必須駐留在父函數中,也稱爲jQuery,.css()是jQuery()的子方法,因此jQuery().css();
  2. 父函數應該返回自身或自身的新實例。

這個例子的工作:

var one = function(num){ 
    this.oldnum = num; 

    this.add = function(){ 
     this.oldnum++; 
     return this; 
    } 

    if(this instanceof one){ 
     return this.one;  
    }else{ 
     return new one(num);  
    } 
} 
var test = one(1).add().add(); 

但是這一次沒有:

var gmap = function(){ 

    this.add = function(){ 
     alert('add'); 

     return this;  
    } 

    if(this instanceof gmap) { 
     return this.gmap; 
    } else{ 
     return new gmap(); 
    } 

} 
var test = gmap.add(); 
+6

函數不返回它們自己,它們返回支持您鏈接的方法的對象。在jQuery的情況下,它是正在運行的節點。 – drudru 2009-07-08 18:00:52

+1

讓每個函數以`return this;`結尾。 – 2012-06-10 01:30:46

+0

@MarcB - 我知道,但是怎麼樣? – 2012-06-10 01:31:32

回答

32

在JavaScript函數是第一類對象。當你定義一個函數時,它是該函數對象的構造函數。換句話說:

var gmap = function() { 
    this.add = function() { 
     alert('add'); 
    return this; 
    } 

    this.del = function() { 
     alert('delete'); 
     return this; 
    } 

    if (this instanceof gmap) { 
     return this.gmap; 
    } else { 
     return new gmap(); 
    } 
} 
var test = new gmap(); 
test.add().del(); 

通過分配

new gmap();
給變量測試你現在建立一個新的對象,「繼承」的所有屬性和方法,從GMAP()構造函數(類)。如果您運行上面的代碼段,則會看到「添加」和「刪除」的提醒。

在上面的示例中,「this」指的是窗口對象,除非將函數包裝在另一個函數或對象中。

鏈接起初對我來說很難理解,至少對我來說是這樣,但是一旦我理解了它,我意識到它可以是一個多麼強大的工具。

4

不幸的是,直接的答案是'不'。即使您可以覆蓋現有的方法(這你也許可以在許多UA,但我懷疑不能在IE瀏覽器),你仍然可以堅持與討厭的重命名:

HTMLElement.prototype.setAttribute = function(attr) { 
    HTMLElement.prototype.setAttribute(attr) //uh-oh; 
} 

你也許可以逃脫最好使用不同的名稱:

HTMLElement.prototype.setAttr = function(attr) { 
    HTMLElement.prototype.setAttribute(attr); 
    return this; 
} 
1

要「重寫」某個功能,但仍然能夠使用原始版本,必須先將原始功能分配給不同的變量。假設一個例子對象:

function MyObject() { }; 

MyObject.prototype.func1 = function(a, b) { }; 

要爲chainability改寫func1,這樣做:

MyObject.prototype.std_func1 = MyObject.prototype.func1; 
MyObject.prototype.func1 = function(a, b) { 
    this.std_func1(a, b); 
    return this; 
}; 

這裏有一個working example。你只需要在你感覺需要可鏈接性的所有標準對象上使用這種技術。

通過你做的這一切工作的時候,你可能會發覺有更好的方式來完成你想要做什麼,喜歡使用已經有chainability建在庫中。 *咳嗽* jQuery *咳嗽*

-3

只需將該方法調用爲var test = gmap()。add();

爲GMAP不是一個函數的變量

0

首先,我要指出,我在我自己的話解釋這一點。

方法鏈接幾乎是調用另一個函數/方法返回的對象的方法。例如(使用jquery):

$('#demo'); 

這個jQuery函數選擇並返回一個jquery對象id爲演示的DOM元素。如果元素是文本節點(元素),我們可以鏈接返回的對象的方法。例如:

$('#demo').text('Some Text'); 

所以,只要一個函數/方法返回一個對象,你可以鏈接返回對象的方法,以原來的語句。

至於爲什麼後者不起作用,請注意使用關鍵字this的時間和地點。這很可能是一個背景問題。當您致電this時,請確保this引用該函數對象本身,而不是窗口對象/全局範圍。

希望有所幫助。