使用new Object()
或者對象字面量均可以建立對象,可是這樣建立的對象過於簡單,不易於對象的屬性與方法的擴展與繼承。
下面講的對象能夠與JavaEE
中的bean
作類比。css
對,首先可能想到的是使用設計模式中的工廠模式設計模式
function createPizza(type) { var o = new Object(); o.type = type; o.bake = function() { alert('Start~'); alert(this.type); alert('End~'); }; return o; } var cheesePizza = createPizza('cheese'); var veggiePizza = createPizza('veggie'); cheesePizza.bake();
工廠模式解決了建立多個相似對象的問題瀏覽器
對象沒法識別,即建立出來的對象沒法經過instanceof
等分析出屬於哪一種類型函數
用構造函數可用來建立特定類型的對象this
// 構造函數首字母遵循OO語言慣例進行大寫 function Pizza(type) { this.type = type; this.bake = function() { alert('Start~'); alert(this.type); alert('End~'); }; } var cheesePizza = new Pizza('cheese'); var veggiePizza = new Pizza('veggie'); cheesePizza.bake();
與工廠模式相比:prototype
return
語句在用new
的時候,會經歷一下4步:設計
若是不使用new,將構造函數當作函數使用,則this指向Global對象(在瀏覽器中爲window對象),固然,能夠使用call方法來指定做用域,例如
var o = new Object(); Pizza.call(o, 'salty'); o.bake();
使用構造函數方法,每一個實例對象都有一個constructor
構造函數屬性,該屬性指向Pizza(使用對象字面量、工廠模式方法建立的對象該屬性指向Object)eslint
cheesePizza.constructor == Pizza
檢查某個對象屬於哪一種類型,通常使用instanceof
,cheesePizza同時屬於Pizza
與Object
(之因此屬於Object,是由於全部對象均繼承於Object)指針
cheesePizza instanceof Pizza; cheesePizza instanceof Object;
與工廠模式相比,構造函數模式可以識別出對象類型
與下面的原型模式相比,可以實現對象屬性的互相獨立,在引用類型屬性上頗有用code
每一個實例對象的方法都是獨立的,致使方法不可以共享
每一個函數(不是實例對象)都有一個prototype
屬性,該屬性是一個指針,指向一個對象,對象的用途是包含全部實例共享的屬性和方法。prototype經過調用構造函數建立的那個對象實例的原型對象。使用原型對象的好處是可讓全部實例對象共享屬性與方法。
function Pizza() { } Pizza.prototype.type = 'original' Pizza.prototype.bake = function() { alert('Start~'); alert(this.type); alert('End~'); }; var cheesePizza = new Pizza(); cheesePizza.type = 'cheese'; var veggiePizza = new Pizza(); veggiePizza.type = 'veggie'; cheesePizza.bake(); veggiePizza.bake();
各個對象共享屬性與方法,同時每一個對象均可以創建本身的屬性,並屏蔽掉原型對象的同名屬性,由於共享屬性與方法,因此如下等式成立
cheesePizza.bake == veggiePizza.bake
也能夠經過對象字面量來重寫整個原型對象:
Pizza.prototype = { type: 'original', bake: function() { alert('Start~'); alert(this.type); alert('End~'); } }
這樣徹底重寫,原型對象上的constructor
屬性再也不指向Pizza
函數(全新的constructor指向Object),不過不影響經過instanceof
來識別對象類型。若是constructor
特別重要的話,能夠顯式將它置爲適當的值:
Pizza.prototype = { constructor: Pizza, type: 'original', bake: function() { alert('Start~'); alert(this.type); alert('End~'); } }
不過這種方式會將constructor
的屬性特徵變爲可枚舉,而默認狀況下它是不可枚舉的,若是想不可枚舉,能夠使用Object.defineProperty()
方法。
對原型對象的修改會體如今實例對象上,即便實例對象先被建立。可是經過對象字面量重寫的原型對象則沒有該動態性
定義在原型對象上的屬性,可以保證在各實例對象上的共享
對於引用類型的屬性,各實例的共享會致使額外的問題。
整合構造函數模式與原型模式,構造函數模式用於定義實例屬性,原型模式用於定義方法和共享屬性。
能夠經過Chrome瀏覽器觀察使用工廠模式建立的cheesePizza對象屬性爲:
cheesePizza {type: "cheese", bake: ƒ} bake: ƒ () type: "cheese" __proto__: constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() __defineGetter__: ƒ __defineGetter__() __defineSetter__: ƒ __defineSetter__() __lookupGetter__: ƒ __lookupGetter__() __lookupSetter__: ƒ __lookupSetter__() get __proto__: ƒ __proto__() set __proto__: ƒ __proto__()
使用構造函數模式建立cheesePizza對象屬性爲:
cheesePizza Pizza {type: "cheese", bake: ƒ} bake: ƒ () type: "cheese" __proto__: constructor: ƒ Pizza(type) __proto__: constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() __defineGetter__: ƒ __defineGetter__() __defineSetter__: ƒ __defineSetter__() __lookupGetter__: ƒ __lookupGetter__() __lookupSetter__: ƒ __lookupSetter__() get __proto__: ƒ __proto__() set __proto__: ƒ __proto__()
使用原型模式建立cheesePizza對象屬性爲:
cheesePizza Pizza {type: "cheese"} type: "cheese" __proto__: bake: ƒ () type: "original" constructor: ƒ Pizza() __proto__: constructor: ƒ Object() hasOwnProperty: ƒ hasOwnProperty() isPrototypeOf: ƒ isPrototypeOf() propertyIsEnumerable: ƒ propertyIsEnumerable() toLocaleString: ƒ toLocaleString() toString: ƒ toString() valueOf: ƒ valueOf() __defineGetter__: ƒ __defineGetter__() __defineSetter__: ƒ __defineSetter__() __lookupGetter__: ƒ __lookupGetter__() __lookupSetter__: ƒ __lookupSetter__() get __proto__: ƒ __proto__() set __proto__: ƒ __proto__()