1.單例模式
保證全局只有一個實例,節(jié)省資源畅形,類似java的靜態(tài)類 static养距,一般用到的地方有歷史記錄、線程池等等
let Singleton=function(){
this.name=1
}
//因為javascript 沒有靜態(tài)類的標(biāo)識 故用閉包保持唯一性 外部無法訪問instance
Singleton.getInstance=(function(){
let instance=null
return function(){
if(!instance ){
instance=new Singleton()
}
return instance
}
})()
let s1=Singleton.getInstance()
let s2=Singleton.getInstance()
console.log(s1===s2)//true
console.log(s1.name)//1
s1.name=2
console.log(s1.name)//2
console.log(s2.name)//2
2.策略類
比如算法日熬,各種算法封裝在策略類棍厌,各種方法的使用交給環(huán)境類
看代碼:
let strategy={
//冒泡排序 逐個調(diào)換位置
A(numbers){
for(let i=0;i<numbers.length;i++){
for(let j=0;j<numbers.length;j++){
let itemNext=numbers[j+1]
let item=numbers[j]
if(itemNext<item){
numbers[j+1]=item
numbers[j]=itemNext
}
}
}
return numbers
},
//選擇排序 每次循環(huán)把最小的放入前置位
B(numbers){
for(let i=0;i<numbers.length;i++){
let itemI=numbers[i]
for(let j=i+1;j<numbers.length;j++){
let itemJ=numbers[j]
if(itemI>itemJ){
numbers[i]=itemJ
numbers[j]=itemI
itemI=itemJ
}
}
}
return numbers
}
}
let content=name=>{
let numbers=[1,3,5,6,1,3,4,6,5]
return strategy[name](numbers)
}
console.log(content('A'))
console.log(content('B'))
3.代理模式
高度解耦,對象保護竖席,易修改耘纱,因為是代理,所以會慢一點
示例代碼:
let myImg={
setSrc(img,src){
img.src=src
}
}
let proxyImg={
setImg(imgNode,src){
//實現(xiàn)圖片懶加載
myImg.setSrc(imgNode,'默認(rèn)圖.png')//占位圖片
let img=new Image()
imgNode.onLoad=function(){
myImg.setSrc(imgNode,src)
}
img.src=src//真正要加載的產(chǎn)品圖片
}
}
let imgNode=document.crateElement('img')
let imgUrl='產(chǎn)品圖.png'
document.body.append(imgUrl)
proxyImg.setImg(imgNode,imgUrl)
4.迭代器模式
迭代器模式是指提供一種方法順序訪問一個集合對象的各個元素毕荐,使用者不需要了解集合對象的底層實現(xiàn)束析。
不太清楚其用途~
let Iterator=obj=>{
let current=0;
let next = ()=>current+=1
let end = ()=>current>=obj.length
let get = ()=>obj[current]
return{
next,
end,
get
}
}
let myIter = Iterator([1, 2, 3]);
while(!myIter.end()) {
console.log(myIter.get()) myIter.next();
}
5.訂閱發(fā)布模式
訂閱-發(fā)布模式定義了對象之間的一種一對多的依賴關(guān)系,當(dāng)一個對象的狀態(tài)發(fā)生改變時憎亚,所有依賴它的對象都可以得到通知员寇。
event.js
class Event{
constructor(){
this._cbs={}
}
//訂閱
on(key,fn){
if(typeof fn != "function"){
return false
}
this._cbs = this._cbs || {};
(this._cbs[key] = this._cbs[key] || []).push(fn)
}
//發(fā)布
emit(){
let _cbs=this._cbs
let key=Array.prototype.shift.apply(arguments)
let affair =_cbs[key]||[]
if(!affair||affair.length<1){
return false
}
for(let fn of affair){
fn.apply(null,arguments)
}
return true
}
//銷毀
off(key,fn){
this._cbs = this._cbs || {}
// all
if (!arguments.length) {
this._cbs = {}
return true
}
var callbacks = this._cbs[key]
if (!callbacks) return
// remove all handlers
if (arguments.length === 1) {
delete this._cbs[key]
return true
}
// remove specific handler
var cb
for (var i = 0, len = callbacks.length; i < len; i++) {
cb = callbacks[i]
if (cb === fn || cb.fn === fn) {
callbacks.splice(i, 1)
break
}
}
return true
}
}
export default Event
//a.js
import Event from event.js
let e=new Event()
e.on('one',v=>{
console.log('訂閱')
console.log(v)
})
e.emit('one',1000)
e.off('one')
e.emit('one',1000)
6.工廠模式
工廠方法模式的實質(zhì)是“定義一個創(chuàng)建對象的接口弄慰,但讓實現(xiàn)這個接口的類來決定實例化哪個類。工廠方法讓類的實例化推遲到子類中進行蝶锋÷剿” 簡單來說:就是把new對象的操作包裹一層,對外提供一個可以根據(jù)不同參數(shù)創(chuàng)建不同對象的函數(shù)扳缕。
class Dog{
run(){
console.log('狗')
}
}
class Cat{
run(){
console.log('貓')
}
}
class Animal{
constructor(name){
name = name.toLocaleLowerCase()
switch(name){
case 'cat':
return new Dog()
case 'dog':
return new Cat()
default:
console.log('沒有哦')
}
}
}
let ss=new Animal('cat')
ss.run()
7.組合模式
用小的子對象構(gòu)造更大的父對象慌闭,而這些子對象也由更小的子對象構(gòu)成 單個對象和組合對象對于用戶暴露的接口具有一致性,而同種接口不同表現(xiàn)形式亦體現(xiàn)了多態(tài)性
// 文件類
class File {
constructor(name) {
this.name = name || "File";
}
add() {
throw new Error("文件夾下面不能添加文件");
}
scan() {
console.log("掃描文件: " + this.name);
}
}
// 文件夾類
class Folder {
constructor(name) {
this.name = name || "Folder";
this.files = [];
}
add(file) {
this.files.push(file);
}
scan() {
console.log("掃描文件夾: " + this.name);
for (let file of this.files) {
file.scan();
}
}
}
let home = new Folder("用戶根目錄");
let folder1 = new Folder("第一個文件夾"),
folder2 = new Folder("第二個文件夾");
let file1 = new File("1號文件"),
file2 = new File("2號文件"),
file3 = new File("3號文件");
// 將文件添加到對應(yīng)文件夾中
folder1.add(file1);
folder2.add(file2);
folder2.add(file3);
// 將文件夾添加到更高級的目錄文件夾中
home.add(folder1);
home.add(folder2);
// 掃描目錄文件夾
home.scan();
8.享元模式
享元模式:運用共享技術(shù)來減少創(chuàng)建對象的數(shù)量躯舔,從而減少內(nèi)存占用驴剔、提高性能。
class ObjectPool{
constructor(){
this._pool=[]
}
create(obj){
return this._pool.length===0?
new obj(this):
this._pool.shift()
}
recover(obj){
return this._pool.push(obj);
}
// 對象池大小
size() {
return this._pool.length;
}
}
// 模擬文件對象
class File {
constructor(pool) {
this.pool = pool;
}
// 模擬下載操作
download() {
console.log(`+ 從 ${this.src} 開始下載 ${this.name}`);
setTimeout(() => {
console.log(`- ${this.name} 下載完畢`); // 下載完畢后, 將對象重新放入對象池
this.pool.recover(this);
}, 100);
}
}
/****************** 以下是測試函數(shù) **********************/
let objPool = new ObjectPool();
let file1 = objPool.create(File);
file1.name = "文件1";
file1.src = "https://download1.com";
file1.download();
let file2 = objPool.create(File);
file2.name = "文件2";
file2.src = "https://download2.com";
file2.download();
setTimeout(() => {
let file3 = objPool.create(File);
file3.name = "文件3";
file3.src = "https://download3.com";
file3.download();
}, 200);
setTimeout(
() =>
console.log(
`${"*".repeat(50)}\n下載了3個文件庸毫,但其實只創(chuàng)建了${objPool.size()}個對象`
),
1000
);