<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
什麼是設計模式
優點
缺點
例子
class DownJacket { production(){ console.log('生產羽絨服') } } class Underwear{ production(){ console.log('生產內衣') } } class TShirt{ production(){ console.log('生產t恤') } } // 工廠類 class clothingFactory { constructor(){ this.downJacket = DownJacket this.underwear = Underwear this.t_shirt = TShirt } getFactory(clothingType){ const _production = new this[clothingType] return _production.production() } } const clothing = new clothingFactory() clothing.getFactory('t_shirt')// 生產t恤
優點
缺點
例子
/* 抽象類 js中abstract是個保留字,實現抽象類只能通過new.target進行驗證, 防止抽象類被直接範例,另外如果子類沒有覆蓋指定方法,則丟擲錯誤 */ class ProductionFlow { constructor(){ if(new.target === ProductionFlow){ throw new Error('抽象類不能被範例') } } production(){ throw new Error('production要被重寫') } materials(){ throw new Error('materials要被重寫') } } class DownJacket extends ProductionFlow{ production(){ console.log(`材料:${this.materials()},生產羽絨服`) } materials(){ return '鴨毛' } } class Underwear extends ProductionFlow{ production(){ console.log(`材料:${this.materials()},生產內衣`) } materials(){ return '絲光棉' } } class TShirt extends ProductionFlow{ production(){ console.log(`材料:${this.materials()},生產t恤`) } materials(){ return '純棉' } } function getAbstractProductionFactory(clothingType){ const clothingObj = { downJacket:DownJacket, underwear:Underwear, t_shirt:TShirt, } if(clothingObj[clothingType]){ return clothingObj[clothingType] } throw new Error(`工廠暫時不支援生產這個${clothingType}型別的服裝`) } const downJacketClass = getAbstractProductionFactory('downJacket') const underwearClass = getAbstractProductionFactory('underwear') const downJacket = new downJacketClass() const underwear = new underwearClass() downJacket.production() // 材料:鴨毛,生產羽絨服 underwear.production() // 材料:絲光棉,生產內衣
優點
缺點
例子
下面繼續用服裝廠的生產流程作為例子。
// 抽象類 class Clothing { constructor() { this.clothingType = '' this.price } } class Underwear extends Clothing { constructor() { super() this.clothingType = 'underwear' this.price = 10 } } class TShirt extends Clothing { constructor() { super() this.clothingType = 't_shirt' this.price = 50 } } class DownCoat extends Clothing { constructor() { super() this.clothingType = 'DownCoat' this.price = 500 } } // 產品 class Purchase { constructor() { this.clothings = [] } addClothing(clothing) { this.clothings.push(clothing) } countPrice() { return this.clothings.reduce((prev, cur)=>cur.price + prev,0) } } // 廠長 class FactoryManager { createUnderwear() { throw new Error(`子類必須重寫 createUnderwear`) } createTShirt() { throw new Error(`子類必須重寫 createTShirt`) } createDownCoat() { throw new Error(`子類必須重寫 DownCoat`) } } // 工人 class Worker extends FactoryManager { constructor() { super() this.purchase = new Purchase() } createUnderwear(num) { for (let i = 0; i < num; i++) { this.purchase.addClothing(new Underwear()) } } createTShirt(num) { for (let i = 0; i < num; i++) { this.purchase.addClothing(new TShirt()) } } createDownCoat(num) { for (let i = 0; i < num; i++) { this.purchase.addClothing(new DownCoat()) } } } // 銷售 class Salesman { constructor() { this.worker = null } setWorker(worker) { this.worker = worker } reserve(clothing) { clothing.forEach((item) => { if (item.type === 'underwear') { this.worker.createUnderwear(item.num) } else if (item.type === 't_shirt') { this.worker.createTShirt(item.num) } else if (item.type === 'DownCoat') { this.worker.createDownCoat(item.num) } else { try { throw new Error('公司暫不生產或不存在該型別的商品') } catch (error) { console.log(error) } } }); const purchase = this.worker.purchase return purchase.countPrice() } } const salesman = new Salesman() const worker = new Worker() salesman.setWorker(worker) const order = [ { type: 'underwear', num: 10 }, { type: 't_shirt', num: 4 }, { type: 'DownCoat', num: 1 } ] console.log(`本次訂單所需金額:${salesman.reserve(order)}`)
const obj = {}
,obj
就是獨一無二的一個物件,在全域性作用域的宣告下,可以在任何地方對它存取,這就滿足了單例模式的條件。優點
缺點
例子
class LoginFrame { static instance = null constructor(state){ this.state = state } show(){ if(this.state === 'show'){ console.log('登入框已顯示') return } this.state = 'show' console.log('登入框展示成功') } hide(){ if(this.state === 'hide'){ console.log('登入框已隱藏') return } this.state = 'hide' console.log('登入框隱藏成功') } // 通過靜態方法獲取靜態屬性instance上是否存在範例,如果沒有建立一個並返回,反之直接返回已有的範例 static getInstance(state){ if(!this.instance){ this.instance = new LoginFrame(state) } return this.instance } } const p1 = LoginFrame.getInstance('show') const p2 = LoginFrame.getInstance('hide') console.log(p1 === p2) // true
優點
缺點
例子
class Jack { english() { return 'I speak English' } } class Xiaoming { chinese() { return '我只會中文' } } // 介面卡 class XiaoHong { constructor(person) { this.person = person } chinese() { return `${this.person.english()} 翻譯: "我會說英語"` } } class Communication { speak(language) { console.log(language.chinese()) } } const xiaoming = new Xiaoming() const xiaoHong = new XiaoHong(new Jack()) const communication = new Communication() communication.speak(xiaoming) communication.speak(xiaoHong)
優點
缺點
例子
class Aircraft { ordinary(){ console.log('發射普通子彈') } } class AircraftDecorator { constructor(aircraft){ this.aircraft = aircraft } laser(){ console.log('發射鐳射') } guidedMissile(){ console.log('發射導彈') } ordinary(){ this.aircraft.ordinary() } } const aircraft = new Aircraft() const aircraftDecorator = new AircraftDecorator(aircraft) aircraftDecorator.ordinary() // 發射普通子彈 aircraftDecorator.laser() // 發射鐳射 aircraftDecorator.guidedMissile() // 發射導彈 // 可以看到在不更改原始碼的情況下對它進行了裝飾擴充套件
優點
缺點
例子
// 員工 class Staff { constructor(affairType){ this.affairType = affairType } applyFor(target){ target.receiveApplyFor(this.affairType) } } // 祕書 class Secretary { constructor(){ this.leader = new Leader() } receiveApplyFor(affair){ this.leader.receiveApplyFor(affair) } } //領導 class Leader { receiveApplyFor(affair){ console.log(`批准:${affair}`) } } const staff = new Staff('升職加薪') staff.applyFor(new Secretary()) // 批准:升職加薪
優點
缺點
例子
function addEvent(el,type,fn){ if(el.addEventlistener){// 高階遊覽器新增事件DOM API el.addEventlistener(type,fn,false) }else if(el.attachEvent){// 低版本遊覽器的新增事件API el.attachEvent(`on${type}`,fn) }else {//其他 el[type] = fn } }
function bindEvent(el,type,selector,fn){ if(!fn){ fn = selector } // 其他程式碼 console.log(el,type,fn) } bindEvent(document.body,'click','#root',()=>{}) bindEvent(document.body,'click',()=>{})
優點
缺點
例子
class Subject { constructor(){ this.observers = {} this.key = '' } add(observer){ const key = observer.project if (!this.observers[key]) { this.observers[key] = [] } this.observers[key].push(observer) } remove(observer){ const _observers = this.observers[observer.project] console.log(_observers,11) if(_observers.length){ _observers.forEach((item,index)=>{ if(item === observer){ _observers.splice(index,1) } }) } } setObserver(subject){ this.key = subject this.notifyAllObservers() } notifyAllObservers(){ this.observers[this.key].forEach((item,index)=>{ item.update() }) } } class Observer { constructor(project,name) { this.project = project this.name = name } update() { console.log(`尊敬的:${this.name} 你預約的專案:【${this.project}】 馬上開始了`) } } const subject = new Subject() const xiaoming = new Observer('滑雪','xiaoming') const A = new Observer('大跳臺','A') const B = new Observer('大跳臺','B') const C = new Observer('大跳臺','C') subject.add(xiaoming) subject.add(A) subject.add(B) subject.add(C) subject.remove(B) // 取消訂閱 subject.setObserver('大跳臺') /** 執行結果 * 尊敬的:A 你預約的專案:【大跳臺】 馬上開始了 * 尊敬的:C 你預約的專案:【大跳臺】 馬上開始了 */
優點
缺點
例子
迭代器分為內部迭代器和外部迭代器,它們有各自的適用場景。
// 內部迭代器表示內部已經定義好了迭代規則,它完全接受整個迭代過程,外部只需一次初始呼叫。 Array.prototype.MyEach = function(fn){ for(let i = 0;i<this.length;i++){ fn(this[i],i,this) } } Array.prototype.MyEach = function(fn){ for(let i = 0;i<this.length;i++){ fn(this[i],i,this) } } [1,2,3,4].MyEach((item,index)=>{ console.log(item,index) })
// 外部迭代器必須顯示的迭代下一個元素。它增加了呼叫的複雜度,但也增加了迭代器的靈活性,可以手動控制迭代的過程。 class Iterator{ constructor(arr){ this.current = 0 this.length = arr.length this.arr = arr } next(){ return this.getCurrItem() } isDone(){ return this.current>=this.length } getCurrItem(){ return { done:this.isDone(), value:this.arr[this.current++] } } } let iterator =new Iterator([1,2,3]) while(!(item=iterator.next()).done) { console.log(item) } iterator.next() /* 下面的資料格式是不是有點熟悉 {done: false, value: 1} {done: false, value: 2} {done: false, value: 3} {done: true, value: undefined} */
優點
缺點
例子
class State { constructor(attack){ this.attack = attack } handle(context){ console.log(this.attack) context.setState(this) } } class Context { constructor(){ this.state = null } getState(){ return this.state } setState(state){ this.state = state } } const q1 = new State('q1 第1擊'), q2 = new State('q2 第2擊'), q3 = new State('q3 第3擊'), context = new Context() q1.handle(context)//q1 第1擊 q2.handle(context)//q2 第2擊 q3.handle(context)//q3 第3擊
優點
缺點
例子
const rules = { cover_img: { must: false, msg: '請上傳封面圖片', val: '' }, name: { must: true, msg: '姓名不能為空', val: '' }, sex: { must: true, msg: '請填寫性別', val: '' }, birthday: { must: false, msg: '請選擇生日', val: '' }, } function verify(){ for(const key in rules){ if(rules[key].must&&!rules[key].val){ console.log(rules[key].msg) } } } verify() // 姓名不能為空 // 請填寫性別
//html----------------- <form action="http:// xxx.com/register" id="registerForm" method="post"> 請輸入使用者名稱:<input type="text" name="userName" /> 請輸入密碼:<input type="text" name="password" /> 請輸入手機號碼:<input type="text" name="phoneNumber" /> <button>提交</button> </form> // js------------------ class Strategies { constructor() { this.rules = {} } add(key, rule) { this.rules[key] = rule return this } } class Validator { constructor(strategies) { this.cache = [] // 儲存檢驗規則 this.strategies = strategies } add(dom, rules) { rules.forEach((rule) => { const strategyAry = rule.strategy.split(':') this.cache.push(() => { const strategy = strategyAry.shift() strategyAry.unshift(dom.value) strategyAry.push(rule.errorMsg) console.log(this.strategies[strategy]) return this.strategies[strategy].apply(dom, strategyAry) }) }); } start() { for (let i = 0,validatorFunc; validatorFunc =this.cache[i++]; ) { const msg = validatorFunc() if (msg) { return msg } } } } const registerForm = document.getElementById('registerForm') // 獲取formDom節點 const strategies = new Strategies() strategies.add('isNonEmpty', function(value, errorMsg) { if (!value) { return errorMsg } }).add('minLength', function(value, length, errorMsg) { if (value.length < length) { return errorMsg } }).add('isMobile', function(value, errorMsg) { if (!/(^1[3|5|8][0-9]{9}$)/.test(value)) { return errorMsg } }) function validataFunc() { const validator = new Validator(strategies.rules) // 多個校驗規則 validator.add(registerForm.userName, [ { strategy: 'isNonEmpty', errorMsg: '使用者名稱不能為空' }, { strategy: 'minLength:10', errorMsg: '使用者名稱長度不能少於10位' } ]) validator.add(registerForm.password, [{ strategy: 'minLength:6', errorMsg: '密碼長度不能少於6位' }]) validator.add(registerForm.phoneNumber, [{ strategy: 'isMobile', errorMsg: '手機號碼格式不對' }]) const errorMsg = validator.start() return errorMsg // 返回錯誤資訊。 } registerForm.onsubmit = function () { const errorMsg = validataFunc() if (errorMsg) { // 如果存在錯誤資訊,顯示錯誤資訊,並且阻止onsubmit預設事件 console.log(errorMsg) return false } }
優點
缺點
例子
// html------------------- <button id="button2">點選按鈕 1</button> <button id="button2">點選按鈕 2</button> <button id="button3">點選按鈕 3</button> // js--------------------- const button1 = document.getElementById('button1'), button2 = document.getElementById('button2'), button3 = document.getElementById('button3'); const MenBar = { refresh:function(){ console.log('重新整理選單目錄') } } const SubMenu = { add:function(){ console.log('增加子選單') }, del:function(){ console.log('刪除子選單') } } function setCommand(el,command){ el.onclick = function(){ command.execute() } } class MenuBarCommand{ constructor(receiver,key){ this.receiver = receiver this.key = key } execute(){ this.receiver[this.key]() } } setCommand(button1,new MenuBarCommand(MenBar,'refresh')) setCommand(button2,new MenuBarCommand(SubMenu,'add')) setCommand(button3,new MenuBarCommand(SubMenu,'del'))
優點
缺點
例子
// 資料夾類 class Folder { constructor(name) { this.name = name this.parent = null; this.files = [] } // 新增檔案 add(file) { file.parent = this this.files.push(file) return this } // 掃描檔案 scan() { console.log(`開始掃描資料夾:${this.name}`) this.files.forEach(file => { file.scan() }); } // 刪除指定檔案 remove() { if (!this.parent) { return } for (let files = this.parent.files, i = files.length - 1; i >= 0; i--) { const file = files[i] if (file === this) { files.splice(i, 1) break } } } } // 檔案類 class File { constructor(name) { this.name = name this.parent = null } add() { throw new Error('檔案下面不能新增任何檔案') } scan() { console.log(`開始掃描檔案:${this.name}`) } remove() { if (!this.parent) { return } for (let files = this.parent.files, i = files.length - 1; i >= 0; i++) { const file = files[i] if (file === this) { files.splice(i, 1) } } } } const book = new Folder('電子書') const js = new Folder('js') const node = new Folder('node') const vue = new Folder('vue') const js_file1 = new File('javascript高階程式設計') const js_file2 = new File('javascript忍者祕籍') const node_file1 = new File('nodejs深入淺出') const vue_file1 = new File('vue深入淺出') const designMode = new File('javascript設計模式實戰') js.add(js_file1).add(js_file2) node.add(node_file1) vue.add(vue_file1) book.add(js).add(node).add(vue).add(designMode) book.remove() book.scan()
優點
缺點
例子
// 抽象父類別 class Beverage { boilWater(){ console.log('把水煮沸') } brew(){ throw new Error('字類必須重寫brew方法') } pourInCup(){ throw new Error('字類必須重寫pourInCup方法') } addCondiments(){ throw new Error('字類必須重寫addCondiments方法') } init(){ this.boilWater() this.brew() this.pourInCup() this.addCondiments() } } // 咖啡類 class Coffee extends Beverage { brew(){ console.log('用沸水沖泡咖啡') } pourInCup(){ console.log('把咖啡倒進杯子') } addCondiments(){ console.log('加糖和牛奶') } } // 茶類 class Tea extends Beverage { brew(){ console.log('用沸水侵泡茶葉') } pourInCup(){ console.log('把茶倒進杯子') } addCondiments(){ console.log('加檸檬') } } const coffee = new Coffee() coffee.init() const tea = new Tea() tea.init()
優點
缺點
例子
let id = 0 // 定義內部狀態 class Upload { constructor(uploadType) { this.uploadType = uploadType } // 點選刪除時 小於3000直接刪除,大於3000通過confirm提示彈窗刪除。 delFile(id) { uploadManager.setExternalState(id,this) if(this.fileSize < 3000){ return this.dom.parentNode.removeChild(this.dom) } if(window.confirm(`確定要刪除該檔案嗎?${this.fileName}`)){ return this.dom.parentNode.removeChild(this.dom) } } } // 外部狀態 class uploadManager { static uploadDatabase = {} static add(id, uploadType, fileName, fileSize) { const filWeightObj = UploadFactory.create(uploadType) const dom = this.createDom(fileName, fileSize, () => { filWeightObj.delFile(id) }) this.uploadDatabase[id] = { fileName, fileSize, dom } } // 建立DOM 並且為button繫結刪除事件。 static createDom(fileName, fileSize, fn) { const dom = document.createElement('div') dom.innerHTML = ` <span>檔名稱:${fileName},檔案大小:${fileSize}</span> <button class="delFile">刪除</button> ` dom.querySelector('.delFile').onclick = fn document.body.append(dom) return dom } static setExternalState(id, flyWeightObj) { const uploadData = this.uploadDatabase[id] for (const key in uploadData) { if (Object.hasOwnProperty.call(uploadData, key)) { flyWeightObj[key] = uploadData[key] } } } } // 定義一個工廠建立upload物件,如果其內部狀態範例物件存在直接返回,反之建立儲存並返回。 class UploadFactory { static createFlyWeightObjs = {} static create(uploadType) { if (this.createFlyWeightObjs[uploadType]) { return this.createFlyWeightObjs[uploadType] } return this.createFlyWeightObjs[uploadType] = new Upload(uploadType) } } // 開始載入 const startUpload = (uploadType, files)=>{ for (let i = 0, file; file = files[i++];) { uploadManager.add(++id, uploadType, file.fileName, file.fileSize) } } startUpload('plugin', [ {fileName: '1.txt',fileSize: 1000}, {fileName: '2.html',fileSize: 3000}, {fileName: '3.txt',fileSize: 5000} ]); startUpload('flash', [ {fileName: '4.txt',fileSize: 1000}, {fileName: '5.html',fileSize: 3000}, {fileName: '6.txt',fileSize: 5000} ]);
優點
缺點
例子
class Order500 { constructor(){ this.orderType = 1 } handle(orderType, pay, stock){ if(orderType === this.orderType&&pay){ console.log('500元定金預約,得到100元優惠券') }else { return 'nextSuccessor' } } } class Order200 { constructor(){ this.orderType = 2 } handle(orderType, pay, stock){ if(orderType === this.orderType&&pay){ console.log('200元訂金預約,得到50元優惠卷') }else { return 'nextSuccessor' } } } class OrderNormal { constructor(){ this.stock = 0 } handle(orderType, pay, stock){ if (stock > this.stock) { console.log('普通購買,無優惠卷') } else { console.log('手機庫存不足') } } } class Chain { constructor(order){ this.order = order this.successor = null } setNextSuccessor(successor){ return this.successor = successor } passRequest(...val){ const ret = this.order.handle.apply(this.order,val) if(ret === 'nextSuccessor'){ return this.successor&&this.successor.passRequest.apply(this.successor,val) } return ret } } console.log(new Order500()) var chainOrder500 = new Chain( new Order500() ); var chainOrder200 = new Chain( new Order200() ); var chainOrderNormal = new Chain( new OrderNormal() ); chainOrder500.setNextSuccessor( chainOrder200 ); chainOrder200.setNextSuccessor( chainOrderNormal ); chainOrder500.passRequest( 1, true, 500 ); // 輸出:500 元定金預購,得到 100 優惠券 chainOrder500.passRequest( 2, true, 500 ); // 輸出:200 元定金預購,得到 50 優惠券 chainOrder500.passRequest( 3, true, 500 ); // 輸出:普通購買,無優惠券 chainOrder500.passRequest( 1, false, 0 ); // 輸出:手機庫存不足
優點
缺點
例子
// html----------- 選擇顏色:<select name="" id="colorSelect"> <option value="">請選擇</option> <option value="red">紅色</option> <option value="blue">藍色</option> </select> <br /> 選擇記憶體:<select name="" id="memorySelect"> <option value="">請選擇</option> <option value="32G">32G</option> <option value="63G">64G</option> </select> <br /> 輸入購買數量:<input type="text" id="numberInput" /> <br /> <div>你選擇了顏色:<span id="colorInfo"></span></div> <div>你選擇了記憶體:<span id="memoryInfo"></span></div> <div>你選擇了數量:<span id="numberInfo"></span></div> <button id="nextBtn" disabled="true">請選擇手機顏色和購買數量</button> // js ------------------- const goods = { "red|32G": 3, "red|16G": 0, "blue|32G": 1, "blue|16G": 6 }, colorSelect = document.getElementById('colorSelect'), memorySelect = document.getElementById('memorySelect'), numberInput = document.getElementById('numberInput'), colorInfo = document.getElementById('colorInfo'), memoryInfo = document.getElementById('memoryInfo'), numberInfo = document.getElementById('numberInfo'), nextBtn = document.getElementById('nextBtn'), mediator = (function () { return { changed(obj) { const color = colorSelect.value, memory = memorySelect.value, number = numberInput.value, stock = goods[`${color}|${memory}`] if (obj === colorSelect) { colorInfo.innerHTML = color } else if (obj === memorySelect) { memoryInfo.innerHTML = memory } else if (obj === numberInput) { numberInfo.innerHTML = number } if (!color) { nextBtn.disabled = true nextBtn.innerHTML = '請選擇手機顏色' return } if (!memory) { nextBtn.disabled = true nextBtn.innerHTML = '請選擇記憶體大小' return } if (Number.isInteger(number - 0) && number < 1) { nextBtn.disabled = true nextBtn.innerHTML = '請輸入正確的購買數量' return } nextBtn.disabled = false nextBtn.innerHTML = '放入購物車' } } })() colorSelect.onchange = function () { mediator.changed(this) } memorySelect.onchange = function () { mediator.changed(this) } numberInput.oninput = function () { mediator.changed(this) }
優點
缺點
例子
const user = { name:'小明', age:'30', getInfo(){ console.log(`姓名:${this.name},年齡:${this.age}`) } } const xiaozhang = Object.create(user) xiaozhang.name = '小張' xiaozhang.age = 18 xiaozhang.getInfo() // 姓名:小張,年齡:18 user.getInfo() // 姓名:小明,年齡:30
優點
缺點
例子
// 棋子 class ChessPieces { constructor(){ this.chess = {} } // 獲取棋子 getChess(){ return this.chess } } // 記錄棋路 class Record { constructor(){ this.chessTallyBook = [] // 記錄棋路 } recordTallyBook(chess){ // console.log(this.chessTallyBook.includes(chess)) const isLoadtion = this.chessTallyBook.some( item=>item.location === chess.location ) if(isLoadtion){ console.log(`${chess.type},${chess.location}已存在其他棋子`) }else { this.chessTallyBook.push(chess) } // this.chessTallyBook.some(item=>item.location === chess.location) } getTallyBook(){ return this.chessTallyBook.pop() } } // 下棋規則 class ChessRule { constructor(){ this.chessInfo = {} } playChess(chess){ this.chessInfo = chess } getChess(){ return this.chessInfo } // 記錄棋路 recordTallyBook(){ return new ChessPieces(this.chessInfo) } // 悔棋 repentanceChess(chess){ this.chessInfo = chess.getTallyBook() } } const chessRule = new ChessRule() const record = new Record() chessRule.playChess({ type:'黑棋', location:'X10,Y10' }) record.recordTallyBook(chessRule.getChess())//記錄棋路 chessRule.playChess({ type:'白棋', location:'X11,Y10' }) record.recordTallyBook(chessRule.getChess())//記錄棋路 chessRule.playChess({ type:'黑棋', location:'X11,Y11' }) record.recordTallyBook(chessRule.getChess())//記錄棋路 chessRule.playChess({ type:'白棋', location:'X12,Y10' }) console.log(chessRule.getChess())//{type:'白棋',location:'X12,Y10'} chessRule.repentanceChess(record) // 悔棋 console.log(chessRule.getChess())//{type:'黑棋',location:'X11,Y11'} chessRule.repentanceChess(record) // 悔棋 console.log(chessRule.getChess())//{type:'白棋',location:'X11,Y10'}
優點
缺點
例子
class Phone { constructor(brand,modle){ this.brand = brand this.modle = modle } showPhone(){ return `手機的品牌:${this.brand.getBrand()},型號${this.modle.getModle()}` } } class Brand { constructor(brandName){ this.brandName = brandName } getBrand(){ return this.brandName } } class Modle { constructor(modleName){ this.modleName = modleName } getModle(){ return this.modleName } } const phone = new Phone(new Brand('華為'),new Modle('mate 40')) console.log(phone.showPhone())
優點
缺點
例子
class Phone { accept() { throw new Error('子類的accept必須被重寫') } } class Mata40Pro extends Phone { accept() { const phoneVisitor = new PhoneVisitor() return phoneVisitor.visit(this) } } class IPhone13 extends Phone { accept() { const phoneVisitor = new PhoneVisitor() return phoneVisitor.visit(this) } } // 存取者類 class PhoneVisitor { visit(phone) { if (phone.constructor === IPhone13) { return { os: 'ios', chip: 'A15仿生晶片', screen: '電容屏' } } else if (phone.constructor === Mata40Pro) { return { os: 'HarmonyOS', chip: 'Kirin 9000', GPUType: 'Mali-G78', port: 'type-c' } } } } const mata40Pro = new Mata40Pro() console.log(mata40Pro.accept())
優點
缺點
例子
class TerminalExpression { constructor(data) { this.data = data } interpret(context) { if (context.indexOf(this.data) > -1) { return true; } return false; } } class OrExpression { constructor(expr1, expr2) { this.expr1 = expr1; this.expr2 = expr2; } interpret(context) { return this.expr1.interpret(context) || this.expr2.interpret(context); } } class AndExpression { constructor(expr1, expr2) { this.expr1 = expr1; this.expr2 = expr2; } interpret(context) { return this.expr1.interpret(context) && this.expr2.interpret(context); } } class InterpreterPatternDemo { static getMaleExpression() { const robert = new TerminalExpression("小明"); const john = new TerminalExpression("小龍"); return new OrExpression(robert, john); } static getMarriedWomanExpression() { const julie = new TerminalExpression("張三"); const married = new TerminalExpression("小紅"); return new AndExpression(julie, married); } static init(args) { const isMale = this.getMaleExpression(); const isMarriedWoman = this.getMarriedWomanExpression(); console.log(`小龍是男性?${isMale.interpret("小龍")}`) console.log(`小紅是一個已婚婦女?${isMarriedWoman.interpret("小紅 張三")}`) } } InterpreterPatternDemo.init()
以上就是javascript的23種設計模式總結大全的詳細內容,更多關於javascript設計模式的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45