工廠模式
function createPerson (name, age) {
var o = new Object()
o.name = name
o.age = age
o.sayName = function () {
alert(this.name)
}
return o
}
var p1 = createPerson('Joey', 19)
var p2 = createPerson('Denise', 22)
缺點:沒解決對象指向問題(結(jié)合下面構(gòu)造函數(shù)模式就明白了)
構(gòu)造函數(shù)模式
// 構(gòu)造函數(shù)常用大寫開頭
function Person (name, age) {
this.name = name
this.age = age
this.sayName = function () {
alert(this.name)
}
}
var p1 = new Person('Joey', 19)
var p2 = new Person('Denise', 22)
// 實例的constructor指向它的構(gòu)造函數(shù),這一塊與原型鏈相關(guān) http://www.itdecent.cn/p/33f6409d89e6
console.log(p1.constructor) // Person
console.log(p2.constructor) // Person
console.log(p1 instanceof Person) // true
console.log(p1 instanceof Object) // true
console.log(p2 instanceof Person) // true
console.log(p2 instanceof Object) // true
除了使用 new 之外,構(gòu)造函數(shù)也是普通的函數(shù),還可以用以下方法調(diào)用:
1.當(dāng)作普通函數(shù)調(diào)用
此舉作用域是在window,相當(dāng)于把函數(shù)里的屬性和方法都添加到window了,在嚴(yán)格模式會報錯
Person('Nicole', 19)
console.log(window.name) // Nicole
console.log(window.age) // 19
window.sayName() // Nicole
2.在另一個對象的作用域調(diào)用
var o = new Object()
Person.call(o, 'Nicole', 19)
console.log(o.name) // Nicole
console.log(o.age) // 19
o.sayName() // Nicole
缺點:每個方法都要在實例中重新創(chuàng)建一邊,p1和p2就各自有一個同名的方法 sayName,創(chuàng)建兩個實現(xiàn)同樣功能的方法似乎不符合經(jīng)濟原則
console.log(p1.sayName === p2.sayName) // false
原型模式
function Person (name, age) {
}
Person.prototype.name = 'Nicole'
Person.prototype.name = 21
Person.prototype.sayName = function () {
alert(this.name)
}
缺點:里面所有屬性和方法都是共享的,不符合實際使用場景
構(gòu)造函數(shù)&原型模式組合
function Person (name, age) {
this.name = name
this.age = age
this.friends = ['Denise', 'Hins']
}
Person.prototype = {
constructor: Person,
sayName: function () {
alert(this.name)
}
}
var p1 = new Person('Joey', 19)
var p2 = new Person('Joey', 19)
p1.friends.push('wyman')
console.log(p1.friends) // ["Denise", "Hins", "wyman"]
console.log(p2.friends) // ["Denise", "Hins"]
console.log(p1.sayName === p2.sayName) // true
構(gòu)造函數(shù)也原型的混雜,是被業(yè)界共同認(rèn)同的一種模式
動態(tài)原型模式
function Person (name, age) {
this.name = name
this.age = age
this.friends = ['Denise', 'Hins']
// if 語句檢查的可以是初始化初始化之后應(yīng)該存在的屬性和方法
if (typeof this.name !== 'function') {
Person.prototype.sayName = function () {
alert(this.name)
}
}
}
console.log(Person.constructor)
var p1 = new Person('Joey', 19)
var p2 = new Person('Hocc', 19)
p1.friends.push('wyman')
console.log(p1.friends) // ["Denise", "Hins", "wyman"]
console.log(p2.friends) // ["Denise", "Hins"]
console.log(p1.sayName === p2.sayName) // true