戲說js之名字空間

 先從簡單的js代碼開始:javascript

 

  
  
  
  
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
  2. <html xmlns="http://www.w3.org/1999/xhtml"
  3. <head> 
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 
  5. <title>無標題文檔</title> 
  6. <script type="text/javascript"
  7. //請養成var的好習慣 
  8. var a=123; 
  9. alert(window.a); 
  10. var b="hello"
  11. alert(window.b); 
  12. window.c=true; alert(window.c);
  13. </script> 
  14. </head> 
  15.  
  16. <body> 
  17. </body> 
  18. </html> 

這個簡單的代碼我想你們都明白,這裏全局範圍內聲明的2個變量,等於爲全局對象window附加2個屬性.關於爲何強調要使用var,後面咱們會看到理由。html

這裏都是簡單的變量,咱們能夠稍微複雜些,來個函數對象和其餘對象。java

 

  
  
  
  
  1. //請養成var的好習慣 
  2. function func1() 
  3.     alert("func1"); 
  4.  
  5. window.func2=function(){alert("func2");}; 
  6.  
  7. var func3=func1; 
  8.  
  9. var func4=new Function("alert(\"func4\");");//晦澀難讀,不常見。 
  10. window.func1(); 

咱們看到這幾個基本相同的代碼(關於function與Function方式的差異不在這裏討論),typeof(window.func****)咱們知道他們是function對象。jquery

也屬於全局範圍。閉包

 

  
  
  
  
  1. //請養成var的好習慣 
  2. var i=123
  3. var s="hello"
  4. var f=4.5555; 
  5. var b=false
  6. var udef;//=undefined 
  7. var nul=null
  8. var o={}; 

但你想過沒有,隨之腳本量的增長全局變量增多,衝突的可能性就加大,隨時都有被覆蓋的風險。jquery插件

比如是往根目錄拷貝文件,同名的可能性在所不免的。咱們想到的辦法是使用層級目錄的方式,軟件開發領域解決這種狀況借用的名字空間的方式(Namespace或者包Package).ide

js沒有在語言層次給予名字空間支持,可是聰明的程序人員們仍是想到了解決的辦法。函數

咱們知道alert(typeof window);你看到的是個object既然全局window是個對象,能承載其餘的變量,那麼好辦了,咱們的通常對象也能夠有這種能力:學習

window.AAA.a這樣不就能夠實現層級管理名字了嗎。ui

  
  
  
  
  1. var MyUtils={};//聲明一個"名字空間" 
  2. MyUtils.a=123; 
  3. MyUtils.b=true
  4. alert(MyUtils.a); 
  5.  
  6. var MyTools={ 
  7.     Test:function() 
  8.     { 
  9.         alert("Test"); 
  10.     }, 
  11.      
  12.     F:function(){ 
  13.         alert("F function"); 
  14.     } 
  15. }; 
  16. MyTools.F(); 
  17.  
  18. MyTools.a="此a非比a."
固然咱們還能夠繼續嵌套,相似多層目錄,讀者能夠本身實驗。 如今OOP大行其道,咱們看看js裏的「類」,用引號稱它是個類,由於js目前沒有給咱們提供Class關鍵字之類的東西,只是在js實現上採用了個小技巧。 咱們來看下,有必要對Function來個簡介,由於他對js裏的類實現有的不可輕視的重要低位。 看下這個就知道對象與Function的千絲萬縷的關係了:、
  
  
  
  
  1. var o=new Object; 
  2. alert(typeof o.constructor); 
輸出function,也就是說js的對象有個contructor屬性指向當成實例化它的那個構造函數。
再實驗下:
  
  
  
  
  1. var MyUtils={};//聲明一個"名字空間" 
  2.  
  3. //聲明構造函數 
  4. MyUtils.Student=function(name,age) 
  5.     this.name=name;  
  6.     this.age=age; 
  7. }; 
  8.  
  9. var o=new MyUtils.Student('張三',23); 
  10. alert(o.constructor); 
咱們驗證了這一點。
  
  
  
  
  1. var MyUtils={};//聲明一個"名字空間" 
  2.  
  3. //聲明構造函數 
  4. MyUtils.Student=function(n,a) 
  5.     this.name=n;     
  6.     this.age=a; 
  7.      
  8.     //能夠實現私有方法 
  9.     function echo() 
  10.     { 
  11.         alert(this.name+"的年齡是:"+this.age); 
  12.     } 
  13.     this.Echo=echo;//公開一個接口對外使用 
  14. }; 
  15.  
  16. var o=new MyUtils.Student('張三',23); 
  17. o.Echo(); 
實例化的問題解決了。固然了有個問題,對於實例方法來講,每一個實例對象保持一個副本不太合理。

還有如何實現OOP裏的繼承思想呢?

不得不提到prototype這個屬性,上面實例化過程
var o1=new MyUtils.Student('張三',23);
new時,會生成一個對象,構造方法裏的this指向這個對象,
	this.name=name;	
	this.age=age;
這些將爲對象的屬性賦值。
有了這個prototype屬性,js還會這這個原型對象裏「繼承一些屬性」;
  
  
  
  
  1. var MyUtils={};//聲明一個"名字空間" 
  2.  
  3. //聲明構造函數 
  4. MyUtils.Student=function(name,age) 
  5.     this.name=name;  
  6.     this.age=age; 
  7.      
  8.     //能夠實現私有方法 
  9.     function echo() 
  10.     { 
  11.         alert(this.name+"的年齡是:"+this.age); 
  12.     } 
  13.     this.Echo=echo;//公開一個接口對外使用 
  14. }; 
  15.  
  16. MyUtils.Student.prototype.Func=function(){alert("共有的.");}; 
  17.  
  18. var o1=new MyUtils.Student('張三',23); 
  19. var o2=new MyUtils.Student('李四',20); 
  20. alert(o1.Func==o2.Func); 
咱們給這個Student的prototype屬性設置屬性Func,
而後實例化2個對象,咱們發現神奇的事情出現了,咱們並無給Student類設置Func屬性,可是實例對象卻具備了,這就是原型的神奇之處。

  
  
  
  
  1. var MyUtils={};//聲明一個"名字空間" 
  2.  
  3. //聲明構造函數 
  4. //普通學生類 
  5. MyUtils.Student=function(name,age) 
  6.     this.name=name;  
  7.     this.age=age; 
  8.      
  9.     //能夠實現私有方法 
  10.     function echo() 
  11.     { 
  12.         return this.name+"的年齡是:"+this.age; 
  13.     } 
  14.     this.Echo=echo;//公開一個接口對外使用 
  15. }; 
  16.  
  17. //大學生 
  18. MyUtils.CollegeStudent=function(name,age,major) 
  19.     MyUtils.Student.call(this,name,age);//有點像base(name,age)或super之類的 
  20.     this.major=major; 
  21. }; 
  22.  
  23. /*MyUtils.CollegeStudent.prototype=new MyUtils.Student(); 
  24. MyUtils.CollegeStudent.prototype.CEcho=function(){ 
  25.     return this.Echo()+","+"專業爲"+this.major; 
  26. };*/ 
  27. var protoObj=new MyUtils.Student(); 
  28. protoObj.CEcho=function(){ 
  29.     return this.Echo()+","+"專業爲"+this.major; 
  30. }; 
  31. MyUtils.CollegeStudent.prototype=protoObj
  32. var o1=new MyUtils.CollegeStudent('張三',23,"化工"); 
  33. var o2=new MyUtils.CollegeStudent('李四',20,"機械"); 
  34. alert(o2.CEcho()); 

 因此關鍵就是那個prototype,咱們把這個模子構造好了。  注意:來幾個實際中的例子 好比jquery.tinyscrollbar.js這個插件源碼裏的: 1.$.tiny = $.tiny || { }; 名字空間(其實就是一個裝東西的口袋對象,一個object而已,跟你平時使用沒什麼差異。 這裏做者寫了好幾個不錯的插件tiny.*****,不妨去看看,因此他都放在了這個空間裏 $.tiny||{}若是$.tiny==undefined則,$.tiny={}至關於。好比頁面引入了坐着多個插件。  2. $.tiny.scrollbar = { ............................. 	}; $.tiny.空間里加個scrollbar屬性,好比存儲了選項配置$.tiny.scrollbar.options  3.關鍵jquery插件擴展: $.fn.tinyscrollbar = function(options) {....} $.fn就至關於$.prototype 咱們給原型添加屬性那麼實例對象(jquery對象的啦)就都具備了tinyscrollbar方法, 好比$("#myscrollbar")這個是jQuery對象,你擴展了jquery以後,就有了$("#myscrollbar").tinyscrollbar();   有必要說一下閉包: 我把它理解爲一個封閉的函數執行體。 好比 全局內var o=123; 人人能夠訪問, 可是 function t1() {   var o=123; } 
function t2() {   var o=「hello」; } 
function t3() {   var o=true; }
如今只有t內能夠訪問到,有點隔離保護的做用。無論怎樣我想我不要誤導你,但但願能給你一個形象的理解。對您的學習不要幫倒忙。 上圖(離散數學裏的閉包不知道跟這個有什麼關係麼?)

R1至關於全局空間,1,2,3表明3個閉包,這裏表明t1,t2,t3的3個執行體。


 

...

相關文章
相關標籤/搜索