Javascript是一種基於對象(Object-Based)的編程語言,常說在javascript中一切都是對象,那么對象究竟是怎么產生的呢?
(一)原始模式
首先說一下我們常見的對象——Object實例。創建Object實例方式有很多,第一種是使用new操作符后跟Object構造函數:
var person=new Object(); person.name="張三"; person.age=21;
另一種方式是對象字面量表示法:
var person={ name:"張三", age:21 }
這兩種方式是生成對象的原始模式。這樣寫有個很明顯的弊端:如果我們需要n多個person對象,那么我們編碼是相當羅嗦苦逼的。既然這樣,那我們需要一個工廠去批量生產這些person實例。
(二)工廠模式
function createPerson(name,age){ var o=new Object(); o.name=name; o.age=age; return o; }
var person1=createPerson("張三",20); var person2=createPerson("李四",21);
這樣每次調用createPerson函數,傳入兩個參數我們就可以創建一個person實例。這樣雖然可以創建對象,但是仍然不能體現“類”與對象實例的關系。
(三)構造函數模式
所謂"構造函數",其實就是一個普通函數,但是內部使用了this變量。對構造函數使用new運算符,就能生成實例,並且this變量會綁定在實例對象上。
function Person(name,age){ this.name=name; this.age=age; } var person1=new Person("張三",21); var person2=new Person("李四",20);
這樣我們就可以通過new Person構造函數創建一個實例對象,慢慢地和我們所認知的“類”與對象實例的關系接近了,我們再進一步拓展一下這個構造函數(畢竟實際當中人的屬性總不單name和age吧)。
function Person(name,age){ this.name=name; this.age=age; this.type="高級動物"; this.speak=function(){ alert(this.name); } } var person1=new Person("張三",21); var person2=new Person("李四",20);
我們為對象添加了type屬性和speek方法。可我們發現,每一個實例對象,type屬性和speak()方法都是一模一樣的內容,每生成一個實例,都必須為重復的內容,多占用一些內存,這樣勢必會造成大量的內存浪費,那有沒有比較方法把一模一樣的內容單獨拿出來共享呢,讓所有的實例對象都能訪問?
(四)原型模式(Prototype模式)
Javascript規定,每一個構造函數都有一個prototype屬性,指向另一個對象。這個對象的所有屬性和方法,都會被構造函數的實例繼承。那我們可以把那些一模一樣的內容(不變的屬性和方法),直接定義在prototype對象上。
function Person(name,age){ this.name=name; this.age=age; } Person.prototype.type="高級動物"; Person.prototype.speak=function(){ alert(this.name); } var person1=new Person("張三",21); var person2=new Person("李四",20); console.log(person1.type); console.log(person2.type); person1.speak(); person2.speak();
這種方式其實就是常說的構造函數模式+原型模式,就是將不同的部分放在構造函數中去構造,把相同的部分放在原型中去共享繼承。
總結:結合上面四種對象產生方式,我們可以根據實際開發需要去創造我們需要的對象,其實,四種模式並沒主次優劣之分,只要能最大限度節省內存和代碼復用高效才是最好的方式。