工廠模式
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)
缺點:沒解決對象指向問題(結合下面構造函數(shù)模式就明白了)
構造函數(shù)模式
// 構造函數(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指向它的構造函數(shù)薪贫,這一塊與原型鏈相關 http://www.reibang.com/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 之外恍箭,構造函數(shù)也是普通的函數(shù),還可以用以下方法調(diào)用:
1.當作普通函數(shù)調(diào)用
此舉作用域是在window瞧省,相當于把函數(shù)里的屬性和方法都添加到window了扯夭,在嚴格模式會報錯
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)
}
缺點:里面所有屬性和方法都是共享的勉抓,不符合實際使用場景
構造函數(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
構造函數(shù)也原型的混雜贾漏,是被業(yè)界共同認同的一種模式
動態(tài)原型模式
function Person (name, age) {
this.name = name
this.age = age
this.friends = ['Denise', 'Hins']
// if 語句檢查的可以是初始化初始化之后應該存在的屬性和方法
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