1 new Object() 先創建一個Object實例,然後為它添加屬性和方法 2 對象字面量法 對象字面量法是創建對象最快捷方便的方式,在很多場景下被使用。 對象字面量法的缺點是創建多個同類對象時,會產生大量重覆代碼,因此有了工廠模式。 3 工廠模式 工廠模式用函數封裝了創建對象的細節,調用函數 ...
1 new Object()
先創建一個Object實例,然後為它添加屬性和方法
var Person = new Object()
Person.name = 'hl'
Person.sayName = function () {
console.log(this.name)
}
2 對象字面量法
對象字面量法是創建對象最快捷方便的方式,在很多場景下被使用。
var Person = {
name: 'hl',
sayName: function () {
console.log(this.name)
}
}
對象字面量法的缺點是創建多個同類對象時,會產生大量重覆代碼,因此有了工廠模式。
3 工廠模式
工廠模式用函數封裝了創建對象的細節,調用函數時傳入對象屬性,然後返回一個對象。
function createPerson (name) {
return {
name: name,
sayName: function () {
console.log(this.name)
}
}
}
var person = createPerson('hl')
var person = new createPerson('hl') // 寄生構造函數模式
通過使用 new 操作符也可以獲得同樣的結果,這種方法被叫做寄生構造函數模式,(應該)與直接調用函數沒什麼區別。
工廠模式雖然解決了創建多個同類對象的問題,卻無法識別對象是哪種具體類型。
4 構造函數模式
通過構造函數創建的對象,可以使用 instanceof 操作符可以確定對象的類型。按照編程慣例,構造函數命名應該大寫,以和普通的函數區別開來。
function Person (name) {
this.name = name
this.sayName = function () {
console.log(this.name)
}
}
p = new Person('hl')
p instanceof Person // true
構造函數的特點:
- 沒有顯示的創建對象
- 屬性和方法直接賦值給this
- 沒有 return 語句
- 使用 new 操作符創建對象
構造函數的缺點是每個方法都會在每個實例上重新創建一遍,造成了記憶體浪費。
5 原型模式
使用原型模式,可以方便的為對象添加屬性和方法。
function Person () {
}
var p = new Person()
Person.prototype.name = 'hl'
Person.prototype.sayName = function () {
console.log(this.name)
}
p.sayName() // hl
原型具有動態性,即先創建對象再修改原型,實例也可以獲得對應的屬性和方法。
原型模式也並非沒有缺點,第一,原型模式不能傳遞初始化參數,導致每個實例都會獲得相同的屬性;第二,對於引用類型的值,所有實例引用的是同一個對象,看下麵的例子:
function Person () {
}
Person.prototype.relative = ['father','mother']
var person1 = new Person()
var person2 = new Person()
person1.relative.push('sister')
console.log(person2.relative) // [ 'father', 'mother', 'sister' ]
修改person1的屬性,person2的屬性也被修改了。實例一般是需要有屬於自己的屬性的,因此很少單獨使用原型模式。
6 組合使用構造函數模式和原型模式
創建對象最常用的方式,就是組合使用構造函數模式和原型模式。構造函數用於自定義屬性,原型模式用於定義共用的屬性和方法。
function Person (name) {
this.name = name
}
Person.prototype.sayName = function () {
console.log(this.name)
}
7 動態原型模式
原型可以在構造函數中初始化,以便更好的封裝對象創建過程。
function Person(name) {
this.name = name
if (typeof this.sayName !== 'function') {
Person.prototype.setName= function (name) {
this.name = name
}
Person.prototype.sayName = function () {
console.log(this.name)
}
}
}
不必用if檢查每一個屬性或方法,只需要檢查原型初始化後應該存在的其中一個屬性或方法即可。
8 穩妥構造函數模式
穩妥對象指的是沒有公共屬性,其屬性和方法也不引用this對象,並且不使用 new 操作符創建對象。適合用在一些需要安全的環境中,防止數據被修改。
function Person (name) {
return {
sayName: function () {
console.log(name)
}
}
}
var person = Person('hl')
穩妥模式創建的對象,除了使用構造函數內定義的方法,沒有辦法修改和訪問傳入到構造函數中的原始數據。