日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

深入剖析js命名空间函数namespace

發布時間:2024/4/17 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入剖析js命名空间函数namespace 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><title>把生成命名空間的方法綁定在jQuery上</title><script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script><script type="text/javascript">// 把生成命名空間的方法綁定在jQuery上 jQuery.namespace = function() { var a=arguments, o=null, i, j, d; for (i=0; i<a.length; i=i+1) { d=a[i].split("."); o=jQuery; for (j=(d[0] == "jQuery") ? 1 : 0; j<d.length; j=j+1) { o[d[j]]=o[d[j]] || {}; o=o[d[j]]; } } return o;}; // 定義命名空間 jQuery.namespace( 'jQuery.first.hello' ); jQuery.first.hello = function() { alert( 'My first hello function' ); }; //調用 jQuery.first.hello(); </script> </head> <body></body> </html>

生成命名空間的方法綁定到jquery上

?

?

阿里員工寫的開源數據庫連接池的druid的源代碼時,發現了其中在jquery的原代碼中又定義了一個命名空間的函數:$.namespace(),其代碼如下:

<script type="text/javascript" src="js/jquery-1.11.1.min.js"></script> <script type="text/javascript"> $.namespace("druid.index"); druid.index=function(){ var i,j; // 定義變量 return { login:function(){ //login 方法的實現 }, submit:function(){ // submit 方法的實現 } } } //使用命名空間的函數 druid.index.login(); druid.index.submit();

?這樣的話,就不會在全局變量區,引入很多的函數,將所有要使用的函數已經變量都放入了命名空間druid.index中,避免了不同js庫中的函數名的沖突。

但是namespace函數的定義如何理解呢?

$.namespace = function() { var a=arguments, o=null, i, j, d; for (i=0; i<a.length; i=i+1) { d=a[i].split("."); o=window; for (j=0; j<d.length; j=j+1) { o[d[j]]=o[d[j]] || {}; o=o[d[j]]; } } return o; };

思考了很久,思考的過程明白一個額外的知識點:window這個引用的是不可覆蓋的。比如我們看下面的代碼:

console.log(window); window = {}; console.log(window); window = null; console.log(window); window = undefined; console.log(window);

打印的結果都是 window, 而不會是 null 或者 undefined。也就是說window這個名稱,實質上是個引用或者說指針,他指向heap上的全局window對象,stack上的window引用指向heap上的全局window對象,這個指向關系是不可覆蓋,不可修改的。上面我修改了stack上的window,視圖讓他指向Null對象,但是修改是無效的。

我們利用firebug來調試看看命名空間到底是如何實現的,我們一步一步的接近目標,先看如下代碼:

(function(){ var o = window;console.log(o); // 打印Window o.druid={};console.log(o); // 打印Windowconsole.log(o.druid); // 打印 Object {} })();

firebug中顯示的對象為:

上面這個結果應該很好理解,因為 o指向了window,所以o.index = {}; 也就相當于 window.index = {}; 在window上定義了一個名叫index的對象。

下面我們在上面的代碼上加碼,在前進一步,接著看:

(function(){ var o = window;console.log(o); // 打印Window o.druid={};console.log(o); // 打印Windowconsole.log(o.druid); // 打印 Object {} o = o.druid;console.log(o); // 打印 Object {}console.log(window); // 打印Windowconsole.log(o.druid); // 打印 undefined })();

?對應firebug中對象和上一步一樣,沒有變化:

上面的代碼中:o = o.druid; 之后,因為 o 是指向 window,為什么console.log(o);? 打印 Object {};而 console.log(window); 打印輸出Window呢?這里的原因是,沒有理解引用的含義。o 和 window 都是stack上的一個變量,他們都指向heap上的全局window對象,我們修改 o 這個引用,讓它指向另外的一個空對象,而這并不會同時修改stack上的window這個引用的指向。也就是就像兩條繩子 a, b 都指向一條船,我讓其中的一條繩子b指向第二條船,并不會影響繩子a還指向第一條船。

o = o.druid; 執行之后,o 不再執行window對象了,而是指向了window.druid對象,那么最后的console.log(o.druid);為什么打印輸出 undefined 呢?很簡單,因為 o 已經指向了 window.druid; 而window.druid是個空對象,其下并沒有個druid的屬性,所以自然就打印輸出 undefined 了。

也就是說最后的console.log(o.druid); 就相當于 console.log(window.druid.druid);

好,理解了上面的代碼,我們在加上一段代碼:

(function(){ var o = window;console.log(o); // 打印Window o.druid={};console.log(o); // 打印Windowconsole.log(o.druid); // 打印 Object {} o = o.druid;console.log(o); // 打印 Object {}console.log(window); // 打印Windowconsole.log(o.druid); // 打印 undefined o.index = {};console.log(o.index); // 打印 Object {}o = o.index;console.log(o.index); // undefined })();

對應的firebug中顯示的對象為:

我們看到了已經形成了我們需要的命名空間:window.druid.index ,其實命名空間是使用對象鏈條來實現的。

因為 o = o.druid; 之后,o 已經指向了 window.druid ,那么 o.index = {}; 就相當于 window.druid.index = {};

而 后面的 o = o.index; 又將 o 對象變成了一個空對象,不再指向 window.druid,打印一個空對象的 index 屬性自然就輸出 undefined.

到這里已經就可以完全理解namespace函數的定義了。

其實核心知識點的有三條:

1)利用了 window 這個特殊引用的不可覆蓋性,不可修改;

2)命名空間其實是對象鏈條來模擬的;

3)理解引用的含義:引用是個在stack上的變量,可以修改它指向不同的對象,要訪問或者說修改他指向的對象,必須使用 “.” 點操作符,比如 o.index ={}; 而單純的修改 o ,比如 o = {}; 并不會修改他指向的對象,因為 沒有訪問到他指向的對象,怎么能修改到他指向的對象呢?

轉載于:https://www.cnblogs.com/hubing/p/4527721.html

總結

以上是生活随笔為你收集整理的深入剖析js命名空间函数namespace的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。