近日,從新學習梳理了JS設計模式,特意在這裏作下筆記記錄下。javascript
class Iterator { constructor(container) { this.list = container.list; this.index = 0; } next() { if (this.hasNext()) { return this.list[this.index++]; } return null; } hasNext() { if (this.index >= this.list.length) { return false; } return true; } } class Container { constructor(list) { this.list = list; } // 生成遍歷器 getIterator() { return new Iterator(this); } } let container = new Container([1, 2, 3, 4, 5]); let iterator = container.getIterator(); while (iterator.hasNext()) { console.log(iterator.next()); }
一、ES6 iteratorjava
function each(data) { // 生成遍歷器 let iterator = data[Symbol.iterator](); // console.log(iterator.next()); 有數據返回{value:1,done:false} // console.log(iterator.next()); 沒有數據返回{value:undefined,done:true} let item = { done: false }; while (!item.done) { item = iterator.next(); if (!item.done) { console.log(item.value); } } } // 測試代碼 let arr = [1, 2, 3]; let nodeList = document.getElementByTagName("p"); let m = new Map(); m.set("a", 100); m.set("b", 200); each(arr); each(nodeList); each(m); // 'Symbol.iterator' 並不知道人人都知道 // 也不是每一個人都須要封裝個each方法 // 所以有了 'for...of' 語法 function each(data) { // data 要有symbol.iterator 屬性 for (let item of data) { console.log(item); } } each(arr); each(nodeList); each(m);
// 狀態(紅燈、黃燈、綠燈) class State { constructor(color) { this.color = color; } handle(context) { console.log(`turn to ${this.color} light`); context.setState(this); } } // 主體 class Context { constructor() { this.state = null; } getState() { return this.state; } setState(state) { this.state = state; } } //test let context = new Context(); let green = new State("green"); let red = new State("red"); let yellow = new State("yellow"); green.handle(context); context.getState(); red.handle(context); context.getState(); yellow.handle(context); context.getState();
一、手寫一個 promisenode
// 狀態機模型 import StateMachine from "javascript-state-machine"; let fsm = new StateMachine({ init: "pending", transitions: [ { name: "resolve", from: "pending", to: "fullfilled" }, { name: "reject", from: "pending", to: "rejected" } ], methods: { // 監聽resolve onResolve: function(state, data) { // state--當前狀態機實例;data--fsm.resolve(xxx)傳遞的參數 data.successList.forEach(fn => fn()); }, // 監聽reject onReject: function(state, data) { // state--當前狀態機實例;data--fsm.resolve(xxx)傳遞的參數 data.failList.forEach(fn => fn()); } } }); // 定義一個Promise class MyPromise { constructor(fn) { this.successList = []; this.failList = []; fn( function() { // resolve函數 fsm.resolve(this); }, function() { // reject 函數 fsm.reject(this); } ); } then(successFn, failFn) { this.successList.push(successFn); this.failList.push(failFn); } } function loadImg() { const promise = new Promise(function(resolve, reject) { let img = document.createElement("img"); img.onload = function() { resolve(img); }; img.onerror = function() { reject(); }; img.src = src; }); return promise; } let src = "https://www.baidu.com/img/a.png"; let result = loadImg(src); result.then( function() { console.log("ok1"); }, function() { console.log("fail1"); } ); result.then( function() { console.log("ok2"); }, function() { console.log("fail2"); } );
// 一個原型對象 const prototype = { getName: function() { return this.first + " " + this.last; }, say: function() { alert("hello"); } }; // 基於原型對象 建立x let x = Object.create(prototype); x.first = "A"; x.last = "B"; alert(x.getName()); x.say(); // 基於原型對象 建立y let y = Object.create(prototype); y.first = "A"; y.last = "B"; alert(y.getName()); y.say();
class Color { constructor(name) { this.name = name; } } class Shape { constructor(name, color) { this.name = name; this.color = color; } draw() { console.log(`${this.color.name} ${this.name}`); } } // test let red = new Color("red"); let yellow = new Color("yellow"); let circle = new Shape("circle", red); circle.draw(); let triangle = new Shape("triangle", yellow); triangle.draw();
<div id="div1" class="container"> <p>123</p> <p>456</p> </div> { tag:'div', attr:{ id:"div1", class:"container" }, children:[ { tag:"p", attr:{}, children:['123'] }, { tag:"p", attr:{}, children:['456'] } ] }
JS 沒有太經典案例設計模式
class User { constructor(type) { this.type = type; } buy() { if (this.type === "ordinary") { console.log("普通用戶購買"); } else if (this.type === "member") { console.log("會員用戶購買"); } else if (this.type === "vip") { console.log("VIP 用戶購買"); } } } // 使用--策略模式 class MemberUser { buy() { console.log("會員用戶購買"); } } class VipUser { buy() { console.log("vip 購買"); } } class OrdinaryUser { buy() { console.log("普通用戶購買"); } } let u1 = new OrdinaryUser(); u1.buy(); let u2 = new MemberUser(); u2.buy(); let u3 = new VipUser(); u3.buy();
class Action { handle() { this.handle1(); this.handle1(); this.handle1(); } handle1() { console.log("1"); } handle2() { console.log("2"); } handle3() { console.log("3"); } }
class Action { constructor(name) { this.name = name; this.nextAction = null; } setNextAction(action) { this.nextAction = action; } handle() { console.log(`${this.name} 審批`); if (this.nextAction !== null) { this.nextAction.handle(); } } } //測試代碼 let a1 = new Action("組長"); let a2 = new Action("經理"); let a3 = new Action("總監"); a1.setNextAction(a2); a2.setNextAction(a3); a1.handle();
class Receive { exec() { console.log("執行"); } } class Command { constructor(receiver) { this.receiver = receiver; } cmd() { console.log("觸發命令"); this.receiver.exec(); } } class Invoker { constructor(command) { this.command = command; } invoke() { console.log("開始"); this.command.cmd(); } } //test //士兵 let soldier = new Receiver(); // 小號手 let trumpeter = new Command(soldier); // 將軍 let general = new Invoker(trumpeter); general.invoke();
// 備忘錄模式 class Memento { constructor(content) { this.content = content; } getContent() { return this.content; } } //備忘錄列表 class CareTaker { constructor() { this.list = []; } add(memento) { this.list.push(memento); } get(index) { return this.list[index]; } } // 編輯器 class Editor { constructor() { this.content = null; } setContent(content) { this.content = content; } getContent() { return this.content; } saveContentToMenento() { return new Memento(this.content); } getContentFromMemento() { this.content = memento.getContent(); } } //test let editor = new Editor(); let careTaker = new CareTaker(); editor.setContent("11"); editor.setContent("22"); careTaker.add(editor.saveContentToMenento()); // 存儲備忘錄 editor.setContent("33"); careTaker.add(editor.saveContentToMenento()); // 存儲備忘錄 editor.setContent("44"); console.log(editor.getContent()); editor.getContentFromMenento(careTaker.get(1)); console.log(editor.getContent()); editor.getContentFromMenento(careTaker.get(0)); console.log(editor.getContent());