通過建立一個Object執行個體
var person = new Object(); person.name = "zhouquan"; person.age = 21; person.sayName = function(){ console.log(this.name); }; person.sayName();//zhouquan
對象字面量方式
var person = { name: "zhouquan", age: 21, sayName:function(){ console.log(this.name); }};person.sayName();//zhouquan
通過普通的建立object執行個體的方式和對象字面量的方式建立對象的方式的缺點在於:這兩種方式都不適合多次建立同一類型的對象。
原廠模式
function createPerson(name, age, job){ var o = new Object(); o.name = name; o.age = age; o.job = job; o.sayName = function(){ console.log(this.name); }; return o; } var person1 = createPerson("zhouquan", 22, "student"); person1.sayName(); //zhouquan var person2 = createPerson("zhouquan2", 23, "Programer"); person2.sayName(); //zhouquan2
函數createPerson()能夠根據接受的參數來構建一個包含所有必要資訊的Person對象。可以無數次的調用這個函數,而每次都會返回一個包含數個屬性的和一個方法的對象。原廠模式雖然解決的建立多個類似對象的問題,但卻沒有解決對象識別的問題(即怎樣知道一個對象的類型)。
建構函式模式
function Person(name, age){ this.name = name; this.age = age; this.sayName = function(){ console.log(this.name); };}var person1 = new Person("zhouquan", 21);person1.sayName(); //zhouquanvar person2 = new Person("zhouquan2", 23);person2.sayName(); //zhouquan2
用這種方式建立對象更原廠模式比起來具有以下幾點區別:
- 沒有顯示的建立對象
- 直接將屬性和方法賦給了this對象
- 沒有return語句
此外,還應該注意到函數名Person使用的大寫字母P。這個是為了區別於其他的函數。
原型模式
function Person(){}Person.prototype.name = "zhouquan";Person.prototype.age = 21;Person.prototype.sayName = function(){ console.log(this.name);};var person1 = new Person();person1.sayName();//zhouquanvar person2 = new Person();person2.sayName();//zhouquan
prototype(原型)屬性,這個屬性是一個指標,指向一個對象,而這個對象的用途是包含可以有特定類型的所有執行個體共用的屬性和方法。使用原型對象的好處也就是可以讓所有的對象執行個體共用它所包含的屬性和方法。
但是這種方法寫起來還是不方便,需要在每一個屬性或者方法前面書寫Person.prototype,我可以結合前面的對象字面量的方法來進行改進:
function Person(){}Person.prototype={ name : "zhouquan", age : 21, sayName : function(){ console.log(this.name); }};var person1 = new Person();person1.sayName();//zhouquanvar person2 = new Person();person2.sayName();//zhouquan
組合使用建構函式模式和原型模式
function Person(name, age){ this.name = name; this.age = age;}Person.prototype={ sayName : function(){ console.log(this.name); }};var person1 = new Person("zhouquan", 21);person1.sayName();//zhouquanvar person2 = new Person("xiaozhou", 21);person2.sayName();//xiaozhou
這種方式是建立自訂類型的最常見方式。建構函式模式用於定義執行個體屬性,而原型模式用於定義方法和共用的屬性。這樣,每個執行個體都會有自己的一份執行個體屬性的副本,但同時又共用這對方法的引用,最大限度地節省了記憶體。另外,這種組合模式還支援向建構函式傳遞參數。可以說,這是用來定義參考型別的一中預設模式。
動態原型模式
function Person(name, age){ this.name = name; this.age = age; if(typeof this.sayName != "function"){ Person.prototype.sayName = function(){ console.log(this.name); }; }}var person1 = new Person("zhouquan", 21);person1.sayName();//zhouquanvar person2 = new Person("xiaozhou", 21);person2.sayName();//xiaozhou
這裡只在sayName()方法不存在的情況下,才會將它添加到原型中,if語句只在初次調用函數時才會執行。其中if語句檢查的可以是初始化之後應該存在的任何屬性或方法,不必用一大堆if語句檢查每個屬性和方法,只要檢查一個即可。需要注意的是,使用動態原型模式時,不能使用對象字面量重寫原型,因為如果在以及建立了執行個體的情況下重寫原型,那麼就會切斷現有執行個體與新原型之間的聯絡。