最近看了一下firefox中javascript的實現,雖然源代碼看不大懂,但對javascript本身有了進一步的認識。javascript是一門通用的腳本語言,它并不僅僅用在web上,而是作為嵌入的腳本語言使用的。不過我看到js除了在web上并沒有很廣泛的應用(和lua,python等比較的話),不知道為什么。Prototype Based VS Class Based javascript和c++/Java等一樣,是html' target='_blank'>面向對象的語言,不同之處在于c++/Java是class based OO language,而javascript是prototype based OO language。 在class based OO language中嚴格區分類和實例(或者說對象);而javascript中只有對象(這點和python也是不同的,在python中Class雖然是一個對象,但是python還是有類Class這個概念的,然后通過這個類創建實例的)。Runtime Member 在C++/Java中,由于類是靜態的(再編譯的時候決定的),所以一個對象有哪些成員函數、成員變量是固定的,不能在運行的時候改變。而在Javascript中,一個對象可以在運行時添加和刪除它的成員,你可以這么寫: var Mary = new Object;Mary.age=10;Mary.eat=function (food) {/*吃東西*/};其實Javascript的成員有點類似于Lua 中的成員或者c++中的關聯容器,例如下面的c++代碼: void eat(void * food){/*吃東西*/}map string,void* Mary;Mary["age"]=(void*)new int(10);Mary["eat"]=(void*)eat;當然上面的代碼純粹亂寫,因為c++的變量有類型的,所以只能用void*來代替。 p.s. 實際上在Javascript中,你可以這么訪問成員: Mary["age"]=10; var str="write";document[str]("hello");Function As Constructor 在Javascript中剛剛創建的Object是沒有任何成員的,可以使用一個構造函數來初始化新建的對象。 function Person(name,age){this.name=name;this.age=age;this.eat=function (food)//成員函數其實不應該這么寫,下面會說明的.{document.write(this.name+"吃了"+food+" br }}var Mary=new Person("Mary",10); var Tom =new Person("Tom",11); Mary.eat("apple");new操作作了2件事: 1.新建一個Object 。 2.把這個Object作為this調用構造函數(new后面的參數)。Function Is Also Object 在Javascript中函數也是一個Object,只不過是一個內建的Object,只不過它的構造函數Javascript本身已經提供,而且可以用特殊的語法來創建Function Object。 function add(x,y){return(x + y);//Perform addition and return results.}var add = new Function("x", "y", "return(x+y)"); 上面兩種語法創建add都是一樣的,同樣你一樣可以寫add.age=10;,類似于Function還有Array,String,Number等內建的對象。這些內建的對象都有一些特殊的成員,使得它們有的能相加(String,Number,Array等),有的能調用(Function),等等。當然Javascript本身不能重載運算符的。 現在可以知道上面Person函數中有什么問題了吧!每次新建一個Person的時候都會新建一個Function Object,而eat方法應該是所有Person都共享的,這就要用過prototype來解決。What''s Prototype 任何對象都有一個Prototype,Prototype是另一個對象。當訪問一個對象的成員的時候,如果這個對象不存在這個成員,那么Javascript會到它的Prototype對象上去找,找不到再到Prototype的Prototype(Prototype也是一個對象所以它也有Prototype)上去找,如此重復,直到不存在Prototype為止(這是特例,你是寫不出代碼讓你的對象的Prototype不存在的)。 那么如何設定一個對象的Prototype呢?每個Function Object都有一個prototype屬性,不過這不是這個函數的Prototype,而是當這個函數作為構造函數的時候,它把prototype屬性作為新建對象的Prototype。(請注意上面我寫的prototype和Prototype的區別,包括下面要寫的) 所以,只要給Person這個函數的prototype屬性增加eat方法,就可以在Mary和Tom中共享這個eat了(可以測試一下Mary.eat==Tom.eat)。上面的代碼只要改成:function Person(name,age){this.name=name;this.age=age;}var Mary=new Person("Mary",10);//創建MaryPerson.prototype.eat=function (food)//修改Prototype{document.write(this.name+"吃了"+food+" br }var Tom =new Person("Tom",11);//創建TomTom.eat("banana");Mary.eat("apple");//即使Mary先創建,eat方法是后添加的。或者: var ClassPerson = new Object;ClassPerson.eat=function (food){document.write(this.name+"吃了"+food+" br }function Person(name,age){this.name=name;this.age=age;}var Mary=new Person("Mary",10);//創建Mary,Mary的Prototype是默認的(默認的是Object)Person.prototype=ClassPerson;//改變Prototypevar Tom =new Person("Tom",11);//創建Tom,Tom的Prototype才是ClassPerson.Tom.eat("banana");//Mary.eat("apple");//不可以,這時Mary的Prototype和Tom的Prototype不是同一個了。通過Prototype可以在對象之間共享方法和屬性,通過設置一層一層的Prototype可以實現繼承,不過不能多重繼承 本文作者:更多編程語言