單例模式
單例模式解決了分組的問題,讓每個(gè)對(duì)象有了自己獨(dú)立的命名空間麦向,但是不能批量生產(chǎn),每一個(gè)新的對(duì)象都要重新寫一份一模一樣的代碼客叉。
var person = {
name:'zhang san',
age:25,
sayName :function () {
console.log(this.name);
}
};
person.sayName();
工廠模式
把實(shí)現(xiàn)同一事情的相同代碼诵竭,放到一個(gè)函數(shù)中,以后如果再想實(shí)現(xiàn)這個(gè)功能兼搏,就不需要重新編寫這些代碼了卵慰,只要執(zhí)行當(dāng)前的函數(shù)即可,
這就是函數(shù)的封裝佛呻,體現(xiàn)了高內(nèi)聚裳朋、低耦合的思想:減少頁面的中的冗余代碼,提高代碼的重復(fù)利用率:
function xxx(name, age) {
var obj = {};
obj.name = name;
obj.age = age;
obj.sayName = function () {
console.log(this.name);
}
return obj;
}
var p1 = xxx('zhang san' , 26);
p1.sayName ();
var p2 = xxx('li si' , 25);
p2.sayName ();
然而吓著,工廠模式雖然解決了創(chuàng)建多個(gè)相似對(duì)象的問題鲤嫡,但是沒有解決對(duì)象的識(shí)別問題,即無法知道一個(gè)對(duì)象的類型绑莺。
隨著 JavaScript 的發(fā)展暖眼,又出現(xiàn)了一種新的模式。
構(gòu)造函數(shù)模式
Script 中的構(gòu)造函數(shù)可以用來創(chuàng)建特定類型的對(duì)象纺裁。像 Object 和 Array 這樣的原生構(gòu)造函數(shù)诫肠,在運(yùn)行時(shí)會(huì)自動(dòng)在執(zhí)行環(huán)境中調(diào)用。
創(chuàng)建一個(gè)新對(duì)象对扶;
將構(gòu)造函數(shù)的作用域賦值給新對(duì)象(指向 this)区赵;
執(zhí)行構(gòu)造函數(shù)中的代碼;
返回新對(duì)象浪南。
function xxx(name, age) {
this.name = name;
this.age = age;
this.sayName = function() {
console.log(this.name);
}
}
const p1 = new xxx('Zhang san', 18);
const p2 = new xxx('Li si', 18);
任何函數(shù)笼才,只要通過 new 操作符來調(diào)用,那么就可以作為構(gòu)造函數(shù)络凿;而任何函數(shù)骡送,如果不通過 new 操作符來調(diào)用昂羡,那它跟普通的函數(shù)也沒有什么兩樣。
構(gòu)造函數(shù)的問題
構(gòu)造函數(shù)雖然好用但也有缺點(diǎn)摔踱。使用構(gòu)造函數(shù)的主要問題虐先,就是每個(gè)方法都要在每個(gè)實(shí)例上重新創(chuàng)建一遍。
function xxx(name, age) {
this.name = name;
this.age = age;
this.sayName = new Function(console.log(this.name));
}
const p1 = new xxx('Zhang san', 18);
const p2 = new xxx('Li si', 18);
用這個(gè)函數(shù)創(chuàng)建 p1 和 p2 都有一個(gè)名為 sayName() 的方法派敷,但這兩個(gè)方法不是同一個(gè) Function 實(shí)例蛹批。
以這種方式創(chuàng)建函數(shù),會(huì)導(dǎo)出現(xiàn)不同的作用域鏈和標(biāo)識(shí)符解析篮愉,雖然它們做的事情是一樣的腐芍,但不同的實(shí)例沒有得到共享。
原型模式
我們創(chuàng)建的每一個(gè)函數(shù)其實(shí)都有一個(gè) prototype 屬性试躏,這個(gè)屬性是一個(gè)指針猪勇,指向一個(gè)對(duì)象,這個(gè)對(duì)象的屬性和方法被由這個(gè)函數(shù)創(chuàng)建的所有實(shí)例共享颠蕴。prototype 對(duì)象被稱為這些實(shí)例的原型對(duì)象泣刹。
function xxx(name, age) {
this.name = name;
this.age = age;
};
xxx.prototype.sayName = function() {
console.log(this.name);
}
我們將 sayName() 方法和所有屬性直接添加到 xxx 的 prototype 屬性中,xxx 的所有實(shí)例就共用了同一個(gè)方法犀被,同時(shí)又保證該方法只在 xxx 作用域內(nèi)上生效椅您。
vue.prototype.showAlert = function (title, content, leftOption = {
title: '取消', onPress: () => {}
}, rightOption = {
title: '確定', onPress: () => {}
},showCancel) {
GlobalConstant.store.commit('ALERT_MUTATION', {
showAlert: true,
title: title,
content: content,
leftText: leftOption.title,
rightText: rightOption.title,
showCancel:showCancel,
leftCallback: () => {
leftOption.onPress()
GlobalConstant.store.commit('ALERT_MUTATION', {
showAlert: false,
showCancel:false
})
},
rightCallback: () => {
rightOption.onPress()
GlobalConstant.store.commit('ALERT_MUTATION', {
showAlert: false,
showCancel:false
})
},
})
}
this.showAlert('提示', '您已有一筆未支付訂單,繼續(xù)下單將取消原訂單',
{ title: '支付原訂單', onPress: () => {this.$router.push({ name: 'MineOrder' })} },
{ title: '繼續(xù)下單', onPress: () => {this.fetchLockSeat()} },
true)