JQuery 命名空间

jQuery encourages using namespaces for methods in the $ namespace, like $.foo.bar() rather than $.bar() . This works for $ because methods don't expect this to refer to anything specific, and the way javascript works is to assign this to the last-named object, so in $.foo.bar() , this refers to $.foo .

This idea fails for plugins, however, since plugins expect this to refer to the jQuery object that started the chain. If I define $.fn.bar = function (){ } , then when $(...).bar() is called, this refers to $(...) , just as we want. But if I define $.fn.foo.bar = function (){ } , then when $(...).foo.bar() is called, this refers to $(...).foo , which is an object that knows nothing about jQuery. There's no way to make an object reference return something else.

But all is not lost. We can define a function that returns an object, and that function can use this to set the returned object to be just like a jQuery object, but with the desired namespaced methods in it. The inefficient way to do that is to copy the new methods into the jQuery object, but if we can manipulate the prototype chain directly (as we can in Firefox) we can add our new methods to the chain without copying.

So a namespacing plugin would be:

  1. ( function  ($) {  
  2.     if ({}.__proto__) {  
  3.         // mozilla & webkit expose the prototype chain directly   
  4.         $.namespace=function  (name) {  
  5.             $.fn[name]=function  namespace() {  
  6.                 // insert this function in the prototype chain   
  7.                 this .__proto__=arguments.callee;  
  8.                 return   this ;  
  9.             };  
  10.             $.fn[name].__proto__=$.fn;  
  11.         };  
  12.         $.fn.$=function  () {  
  13.             this .__proto__=$.fn;  
  14.             return   this ;  
  15.         };  
  16.     }  
  17.     else  {  
  18.         // every other browser; need to copy methods   
  19.         $.namespace=function  (name) {  
  20.             $.fn[name]=function  namespace() {  
  21.                 return   this .extend(arguments.callee);  
  22.             };  
  23.         };  
  24.         $.fn.$=function  () {  
  25.             // slow but restores the default namespace   
  26.             var  len= this .length;  
  27.             this .extend($.fn);  
  28.             this .length=len;  
  29.             // $.fn has length = 0, which messes everything up   
  30.             return   this ;  
  31.         };  
  32.     }  
  33. })(jQuery);  

 

And you could use it like:

  1. $.namespace( 'danny' );  
  2. $.namespace('danny2' );  
  3. $.fn.danny.foo=function  () {  
  4.     return   this .css( 'color' , 'green' )  
  5. };  
  6. $.fn.danny2.foo=function  (x) {  
  7.     alert(x);  
  8.     return   this ;  
  9. };  
  10. // now we have two different methods "foo"   
  11. $('p' ).danny().foo();  
  12. // colors paragraphs green   
  13. $('p' ).danny2().foo( 'Hello, world' );  
  14. // alerts 'Hello, world'   
  15. $('p' ).danny().foo().danny2().foo( 'Hello, world' );  
  16. // chaining works   
  17. $.fn.danny.add=function  (a,b) {  
  18.     alert(a+b);  
  19.     return   this ;  
  20. };  
  21. // defines a function with the same name as a real jQuery one   
  22. $('p' ).danny().add(1,2).$().add( 'div' );  
  23. // the $() plugin restores the real jQuery namespace to a chain    

The namespacing is per-chain only; $('p' ).danny() does not affect any subsequent statements. Plugins that call pushStack will reset the namespacing, but in general the namespace function should be called right before the method, so that should not be an issue.

This is inefficient, obviously, adding an extra function call and possible a lot of copying with extend , but for most code that is insignificant.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值