淺談JavaScript的面向物件程式設計(三)
阿新 • • 發佈:2022-04-29
前面已經對JavaScript的面向物件程式設計作了簡單的介紹,包括了物件的屬性、物件的工廠模式、建構函式和原型等。通過介紹,這些建立物件的方法依然有不少優化和改進的地方。
組合使用建構函式模式和原型模式
建立自定義型別的最常用方式就是使用組合建構函式和原型模式。建構函式用於定義例項屬性,原型用於定義共享的屬性和方法。每個例項都有自己的例項副本,同時又共享了原型屬性和方法,節省了記憶體。還支援向函式傳遞引數。
1 function Person(name,age,sex){ 2 this.name=name; 3 this.age=age; 4 this.sex=sex; 5 } 6 Person.prototype={ 7 constructor:Person, 8 getName:function(){ 9 return this.name; 10 } 11 } 12 var person1 = new Person("jack",18,"man"); 13 var person2 = new Person("helen",19,"woman"); 14 console.log(person1.getName());//jack 15 console.log(person2.getName());//helen 16 console.log(person1.getName===person2.getName);//true
上面的程式碼中,例項屬性都是在建構函式中定義的。在原型中定義了contructor和getName方法,原型中的方法由所有的例項共享。14行和15行輸出的結果不相同,因為例項屬性定義再建構函式中,而16行輸出true,則證明兩個例項的getName指向同一個棧記憶體。
動態原型模式
上面的例子中,我們將函式的宣告和原型的定義是分開的。為了解決這一點,我們可以在建構函式中初始化原型。
1 function Person(name,age,sex){ 2 this.name=name; 3 this.age=age; 4 this.sex=sex; 5 if(typeof this.getName!="function"){ 6 Person.prototype.getName=function(){ 7 return this.name; 8 } 9 } 10 } 11 var person1 = new Person("jack",18,"man"); 12 var person2 = new Person("helen",19,"woman"); 13 console.log(person1.getName());//jack 14 console.log(person2.getName());//helen 15 console.log(person1.getName===person2.getName);//true
上面的程式碼中,我們在建構函式中聲明瞭屬性以及原型的方法。但是我們在5行有判斷,只有當函式不存在的時候才呼叫,避免了函式的多次呼叫。
寄生建構函式模式
通常情況下,我們使用上面的幾種模式已經可以滿足多種建立物件的需求了。JavaScript還為我們提供了寄生建構函式模式。這種模式的基本思想是建立一個函式,該函式僅僅是用來封裝物件的程式碼,並返回建立的物件。
1 function Person(name,age,sex){ 2 var obj =new Object(); 3 obj.name=name; 4 obj.age=age; 5 obj.sex=sex; 6 obj.getName=function(){ 7 return this.name; 8 } 9 return obj; 10 } 11 var person = new Person("jack",18,"man"); 12 console.log(person.getName());//jack
上面的程式碼使用寄生建構函式模式建立了物件person,上面的物件,除了用new 來構造物件外,其他的與工廠模式建立物件的過程是一致的。通過寄生建構函式模式建立的物件,與建構函式本身並沒有關係,建構函式返回的物件與在建構函式建立的物件並沒有關係。不能通過instanceof來確定物件的型別。