2011-06-11 14 views
10

jQuery能做什麼$("#foo").addClass("bar")$.ajax()

我正在創建一個微型javascript框架,並且想要創建一個對象的新實例,例如$("#hello")。有了這個對象,就有了相關的方法,如addClass,css等,就像使用jQuery一樣。所以我可以做類似

$("#foo").addClass("remove").css("color", "red"); 

我已經成功地創建了這個。但是,當我想從這個對象調用方法時,如$.ajax,構造函數被覆蓋,我可以調用$ .ajax,但不能調用$(「#foo」)。

基本上,jQuery如何做到這一點?

+3

jQuery使用黑魔法。認真的說,很好的問題+1 – fehays 2011-06-11 00:33:41

+1

我認爲你可以通過查看jQuery源代碼學到很多東西。 – 2011-06-11 01:44:37

+4

@FelixKling你也學到了很多「哦,我不應該這樣做」 – Raynos 2011-06-11 02:42:18

回答

10

好吧,$函數不僅是一個函數,而且是一個對象,就像所有函數一樣。所以它可以有方法。那就是ajax,這是$函數的一種方法。所以我們可以這樣做:

$ = function(obj) { 
    // some code 
}; 
$.ajax = function (arg1, arg2) { 
    // some ajax-y code 
}; 

到目前爲止好。現在,我們在$函數中究竟做了什麼?那麼它必須返回一個對象,並且該對象必須定義一些好的方法。所以我們需要一個構造函數(給我們新的對象)和一個原型(爲這些對象提供漂亮的方法)。

$ = function(obj) { 
    var myConstructor = function (obj) { 
    this.wrappedObj = obj; 
    }; 

    myConstructor.prototype = { 
    niftyMethod: function() { 
     // do something with this.wrappedObj 
     return this; // so we can chain method calls 
    }, 
    anotherNiftyMethod: function (options) { 
     // do something with this.wrappedObj and options 
     return this; 
    } 
    }; 

    return new myConstructor(obj); 
}; 

所以我們有它。我們可以這樣做:

var mySnazzObject = $("whatever"); 
mySnazzObject.niftyMethod().anotherNiftyMethod(true);   

我們可以做到這一點:

$.ajax("overthere.html", data); 

顯然jQuery的做了很多的赫克不止於此,它確實是在一些非常令人印象深刻的方式,但是這就是大概的概念。

UPDATE:AS @Raynos非常友善,如果沒有提供建設性答案,我的原始代碼就會創建無限的原型。因此,我們利用匿名autoexecuting功能的單獨聲明構造函數和原型:

(function() { 
    var myConstructor = function (obj) { 
    this.wrappedObj = obj; 
    }; 

    myConstructor.prototype = { 
    niftyMethod: function() { 
     // do something with this.wrappedObj 
     return this; // so we can chain method calls 
    }, 
    anotherNiftyMethod: function (options) { 
     // do something with this.wrappedObj and options 
     return this; 
    } 
    }; 

    var $ = function(obj) { 
    return new myConstructor(obj);   
    }; 

    $.ajax = function (arg1, arg2) { 
    // some ajax-y code 
    }; 

    window.$ = $; 
}()); 
+1

當每次調用'$'時創建一個新的原型對象時,原型的意義何在。 – Raynos 2011-06-11 02:43:06

+0

@Raynos:你走了,我過於簡單了。 – jmbucknall 2011-06-11 02:51:21

+0

@patrick_dw你總是可以自己發表答案。 – Raynos 2011-06-11 04:10:22

15
$ = function(arg) { console.log("$ function called with " + arg); } 
$.ajax = function(arg) {console.log("$.ajax called with " + arg);} 
$('foo'); 
$.ajax('bar'); 

http://jsfiddle.net/ac7nx/

我不認爲這裏有任何魔法。 $只是全局函數的名稱。請記住,在JavaScript中,函數是第一類對象,它們可以有自己的屬性,包括子函數,這就是$.ajax

既然你提到了構造函數,我應該注意到在這裏沒有使用OO對象,只是普通的函數(沒有new關鍵字),所以構造函數不會參與這個。如果您使用的是new關鍵字,那可能是您感到困惑的地方。如果你想讓$('#foo')返回一個新的對象,那麼在$函數的代碼中,你應該使用new創建一個新對象並返回它,這是jQuery的功能,但$函數本身不是構造函數,不應該使用new來調用。或者在類似$('#someID')的情況下,在該函數內部,jQuery從DOM獲取元素對象,然後返回該對象,但$只是一個常規函數,其返回值是一個對象,而不是構造函數。

1

兩種不同的東西:

$.ajax是的jQuery的原型函數調用AJAX。

雖然$(「富」)是jQuery函數的呼叫並且取決於foo的類型以不同的方式反應。在http://api.jquery.com/jQuery你可以看到jQuery(幾乎與$相同)可以對三種不同類型作出反應:選擇器,html或回調。

+2

'$ .ajax'沒有原型。它只是一個對象(函數)的單個實例的屬性。原型函數是可以從jQuery函數返回的對象訪問的函數。 – user113716 2011-06-11 03:42:41

0

可以模仿神奇的jQuery行爲如下:

//define 
var _$ = {}; 
var $ = function(selector) { 
      _$.html = function(args) { 
        alert("Doing the method 'html' with arguments " + args 
          + " for selector " + selector); 
        return _$; //needed for pipeline 
     }; 
     return _$; 
}; 

$.ajax = function(args){alert("Doing the method 'ajax' "); } 

//and try 
$("selector1").html("args1").html("args2"); 
$.ajax("args2"); 
相關問題