先從簡單的js代碼開始:javascript
- <!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>
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- <title>無標題文檔</title>
- <script type="text/javascript">
- //請養成var的好習慣
- var a=123;
- alert(window.a);
- var b="hello";
- alert(window.b);
- window.c=true; alert(window.c);
- </script>
- </head>
- <body>
- </body>
- </html>
這個簡單的代碼我想你們都明白,這裏全局範圍內聲明的2個變量,等於爲全局對象window附加2個屬性.關於爲何強調要使用var,後面咱們會看到理由。html
這裏都是簡單的變量,咱們能夠稍微複雜些,來個函數對象和其餘對象。java
- //請養成var的好習慣
- function func1()
- {
- alert("func1");
- }
- window.func2=function(){alert("func2");};
- var func3=func1;
- var func4=new Function("alert(\"func4\");");//晦澀難讀,不常見。
- window.func1();
咱們看到這幾個基本相同的代碼(關於function與Function方式的差異不在這裏討論),typeof(window.func****)咱們知道他們是function對象。jquery
也屬於全局範圍。閉包
- //請養成var的好習慣
- var i=123;
- var s="hello";
- var f=4.5555;
- var b=false;
- var udef;//=undefined
- var nul=null;
- var o={};
但你想過沒有,隨之腳本量的增長全局變量增多,衝突的可能性就加大,隨時都有被覆蓋的風險。jquery插件
比如是往根目錄拷貝文件,同名的可能性在所不免的。咱們想到的辦法是使用層級目錄的方式,軟件開發領域解決這種狀況借用的名字空間的方式(Namespace或者包Package).ide
js沒有在語言層次給予名字空間支持,可是聰明的程序人員們仍是想到了解決的辦法。函數
咱們知道alert(typeof window);你看到的是個object既然全局window是個對象,能承載其餘的變量,那麼好辦了,咱們的通常對象也能夠有這種能力:學習
window.AAA.a這樣不就能夠實現層級管理名字了嗎。ui
固然咱們還能夠繼續嵌套,相似多層目錄,讀者能夠本身實驗。 如今OOP大行其道,咱們看看js裏的「類」,用引號稱它是個類,由於js目前沒有給咱們提供Class關鍵字之類的東西,只是在js實現上採用了個小技巧。 咱們來看下,有必要對Function來個簡介,由於他對js裏的類實現有的不可輕視的重要低位。 看下這個就知道對象與Function的千絲萬縷的關係了:、
- var MyUtils={};//聲明一個"名字空間"
- MyUtils.a=123;
- MyUtils.b=true;
- alert(MyUtils.a);
- var MyTools={
- Test:function()
- {
- alert("Test");
- },
- F:function(){
- alert("F function");
- }
- };
- MyTools.F();
- MyTools.a="此a非比a.";
- var o=new Object;
- alert(typeof o.constructor);
輸出function,也就是說js的對象有個contructor屬性指向當成實例化它的那個構造函數。 再實驗下:
- var MyUtils={};//聲明一個"名字空間"
- //聲明構造函數
- MyUtils.Student=function(name,age)
- {
- this.name=name;
- this.age=age;
- };
- var o=new MyUtils.Student('張三',23);
- alert(o.constructor);
咱們驗證了這一點。
- var MyUtils={};//聲明一個"名字空間"
- //聲明構造函數
- MyUtils.Student=function(n,a)
- {
- this.name=n;
- this.age=a;
- //能夠實現私有方法
- function echo()
- {
- alert(this.name+"的年齡是:"+this.age);
- }
- this.Echo=echo;//公開一個接口對外使用
- };
- var o=new MyUtils.Student('張三',23);
- o.Echo();
實例化的問題解決了。固然了有個問題,對於實例方法來講,每一個實例對象保持一個副本不太合理。 還有如何實現OOP裏的繼承思想呢? 不得不提到prototype這個屬性,上面實例化過程 var o1=new MyUtils.Student('張三',23); new時,會生成一個對象,構造方法裏的this指向這個對象, this.name=name; this.age=age; 這些將爲對象的屬性賦值。 有了這個prototype屬性,js還會這這個原型對象裏「繼承一些屬性」;
- var MyUtils={};//聲明一個"名字空間"
- //聲明構造函數
- MyUtils.Student=function(name,age)
- {
- this.name=name;
- this.age=age;
- //能夠實現私有方法
- function echo()
- {
- alert(this.name+"的年齡是:"+this.age);
- }
- this.Echo=echo;//公開一個接口對外使用
- };
- MyUtils.Student.prototype.Func=function(){alert("共有的.");};
- var o1=new MyUtils.Student('張三',23);
- var o2=new MyUtils.Student('李四',20);
- alert(o1.Func==o2.Func);
咱們給這個Student的prototype屬性設置屬性Func, 而後實例化2個對象,咱們發現神奇的事情出現了,咱們並無給Student類設置Func屬性,可是實例對象卻具備了,這就是原型的神奇之處。
- var MyUtils={};//聲明一個"名字空間"
- //聲明構造函數
- //普通學生類
- MyUtils.Student=function(name,age)
- {
- this.name=name;
- this.age=age;
- //能夠實現私有方法
- function echo()
- {
- return this.name+"的年齡是:"+this.age;
- }
- this.Echo=echo;//公開一個接口對外使用
- };
- //大學生
- MyUtils.CollegeStudent=function(name,age,major)
- {
- MyUtils.Student.call(this,name,age);//有點像base(name,age)或super之類的
- this.major=major;
- };
- /*MyUtils.CollegeStudent.prototype=new MyUtils.Student();
- MyUtils.CollegeStudent.prototype.CEcho=function(){
- return this.Echo()+","+"專業爲"+this.major;
- };*/
- var protoObj=new MyUtils.Student();
- protoObj.CEcho=function(){
- return this.Echo()+","+"專業爲"+this.major;
- };
- MyUtils.CollegeStudent.prototype=protoObj;
- var o1=new MyUtils.CollegeStudent('張三',23,"化工");
- var o2=new MyUtils.CollegeStudent('李四',20,"機械");
- 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個執行體。
...