jq的擴充函數解析,jq擴充函數解析
上面兩節中,已經大概剖析了jq的基本架構。然後,還有jq一相當重要的功能沒有提及,那就是jq的擴充功能。
Jq一共有兩種擴充功能,一種是類的靜態擴充,一種是類執行個體的擴充。
但其實在jq中,兩個都是統一使用一個函數的。先來看下一段代碼:
(function(){var test=function(selector){return new test.prototype.init(selector);}test.prototype={init:function(selector){this.elem=document.getElementById(selector);return this;},name:function(){alert(123)return this;},pwd:function(){alert(456)},hide:function(){this.elem.setAttribute('style','display:none;');return this;},getAttribute:function(){return this.elem.getAttribute('style');}}test.extend=test.prototype.extend=function(op){for (var name in op) {this[name]=op[name]}}test.prototype.init.prototype=test.prototype;$=test;}())
這樣,我們同樣也可以使用兩種方法對我們上面那個架構進行擴充了。
使用方法是:
$.prototype.extend({h:function(){alert(3)}});$('t').h();
這是類執行個體的擴充,還有一種是類靜態擴充:
$.extend({h:function(){alert(1)}});$.h();
在jq中,對類執行個體的擴充是使用$.fn.extend(),我們只要js中加上:
test.fn=test.prototype就可以了。
這裡,為什麼不使用
test.extend=function(op){
test.prototype=op;
}
這是因為test.prototype=op會將原先原型中的方法和屬性刪除掉,替換成op;
但是又為什麼不使用:
test.extend=function(op){
for(var name in op) {
eval("test.prototype."+name+"=op."+name)
}
}
這是因為如果這樣添加後,要調用h()這個方法,便不能使用$.h(),而是需要使用$.protype.h()
因為$只是一個函數,其this指標指向window。
在這裡還涉及到一個知識點,那就是訪問某個執行個體的時候,會進行兩次搜尋,第一次是搜尋改執行個體本身,第二次搜尋是搜尋this指標指向的對象的protype中的屬性和方法。
像$.h(),其this指標是指向window的,因此第二次搜尋的是window中的原型,而不是test中的原型。
但如果是:
test.extend=function(op){
this.prototype=op;
}
這樣也不可取,因為這樣的話,任何對象都可以調用我們的h()方法,因為this指標是指向window的。
因此,最可取的,還是早先我們那種實現方法,即可正確運行,有加快速度(在第一次搜尋中就能調用).
注意:new 某個函數()後,實際上將其this指標指向window改而指向函數執行個體本身的。