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();
這種方式其實就是常說的建構函式模式+原型模式,就是將不同的部分放在建構函式中去構造,把相同的部分放在原型中去共用繼承。
總結:結合上面四種對象產生方式,我們可以根據實際開發需要去創造我們需要的對象,其實,四種模式並沒主次優劣之分,只要能最大限度節省記憶體和代碼複用高效才是最好的方式。