近日,從新學習梳理了JS設計模式,特意在這裏作下筆記記錄下。javascript
簡單一句話歸納 就是 return 一個 new 實例html
class SingleObject { login() { console.log("login..."); } } SingleObject.getInstance = (function() { let instance; return function() { if (!instance) { instance = new SingleObject(); } return instance; }; })(); let obj1 = SingleObject.getInstance(); obj1.login(); let obj2 = SingleObject.getInstance(); obj2.login(); console.log("obj1===obj2", obj1 === obj2); console.log("分割線"); let obj3 = new SingleObject(); obj3.login(); console.log("obj1===obj3", obj1 === obj3);
一、 jQuery $ 只有一個vue
if (window.jQuery !== null) { return window.jQuery; } else { // 進行初始化操做 }
二、 登陸框java
class LoginForm { constructor() { this.state = "hide"; } show() { if (this.state === "show") { alert("已經顯示"); return; } this.state = "show"; console.log("登陸框已經顯示"); } hide() { if (this.state === "hide") { alert("已經隱藏"); return; } this.state = "hide"; console.log("登陸框已經隱藏"); } } LoginForm.getInstance = (function() { let instance; return function() { if (!instance) { instance = new LoginForm(); } return instance; }; })(); let login1 = LoginForm.getInstance(); login1.show(); let login2 = LoginForm.getInstance(); login2.show(); console.log("login1===login2", login1 === login2);
三、 vuex 和 redux 中的 store state 是單例模式node
class Adaptee { specificRequest() { return "德國標準插頭"; } } class Target { constructor() { this.adaptee = new Adaptee(); } request() { let info = this.adaptee.specificRequest(); return `${info} - 轉換器 - 中國標準插頭`; } } let target = new Target(); let res = target.request(); console.log(res);
一、 封裝舊接口react
// 本身封裝的ajax 以下 ajax({ url: "/getData", type: "POST", dataType: "json", data: { id: "123" } }).done(function() {}); // 但由於歷史緣由,代碼中全是; // $.ajax({...}) // 作一層適配器 var $ = { ajax: function(option) { return ajax(option); } };
二、Vue computed 場景ajax
<div id="example"> <p>Origin Message:{{message}}</p> <p>Computed Message:{{reversedMessage}}</p> </div>
var vm = new Vue({ el: "#example", data: { message: "Hello" }, computed: { // 計算屬性的 getter reversedMessage: function() { // `this`指向vm實例 return this.message .split("") .reverse() .join(""); } } });
// 基礎代碼 @decorator class A {} // 等同於 class A {} a = decorator(A) || A;
// 裝飾器傳參 加參數 function testDesc(isDec) { return function(target) { target.isDec = isDec; }; } @testDesc(true) class Demo { //... } alert(Demo.isDec);
一、 ES7 裝飾器vuex
@testDesc class Demo {} function testDesc(target) { target.isDec = true; } alert(Demo.isDec);
//一、mixin 實例 function mixins(...list) { return function(target) { Object.assign(target.prototype, ...list); }; } const Foo = { foo() { alert("foo"); } }; @mixins(Foo) class MyClass {} let obj = new MyClass(); obj.foo();
// 例 1 function readonly(target, name, descriptor) { //descriptor 是描述對象 (Object.defineProperty中會用到),原來的值以下 //{ // value:specifiedFunction, // enumerable:false, // configurable:true, // writable:true //} descriptor.writable = false; return descriptor; } class Person { constructor() { this.first = "A"; this.last = "B"; } // 裝飾方法 @readonly name() { return `${this.first} ${this.last}`; } } var p = new Person(); console.log(p.name()); //p.name=function(){} // 這裏會報錯,由於name 是隻讀屬性
二、例 2json
function log(target, name, descriptor) { var oldValue = descriptor.value; descriptor.value = function() { console.log(`Calling ${name} with`, arguments); return oldValue.apply(this, arguments); }; return descriptor; } class Math { //裝飾方法 @log add(a, b) { return a + b; } } const math = new Math(); const result = math.add(2, 4); console.log("result", result);
class ReadImg { constructor(fileName) { this.fileName = fileName; this.loadFromDisk(); } display() { console.log(`display...` + this.fileName); } loadFromDisk() { console.log(`load...` + this.fileName); } } class ProxyImg { constructor() { this.realImg = new ReadImg(); } display() { this.realImg.display(); } } let proxyImg = new ProxyImg("1.png"); proxyImg.display();
一、javascript 點擊事件redux
<div id="div1"> <a href="#">a1</a> <a href="#">a2</a> <a href="#">a3</a> <a href="#">a4</a> </div> <script> var div1 = document.getElementById("div1"); div1.addEventListener("click", function(e) { var target = e.target; if (target.nodeName === "A") { alert(target.innerHTML); } }); </script>
二、明星經紀人
// 明星 let star = { name: "劉德華", age: 50, phone: "15987452635" }; // 經紀人 let agent = new Proxy(star, { get: function(target, key) { if (key === "phone") { //返回經紀人本身手機號 return "15911111111"; } if (key === "price") { // 明星不報價,經紀人報價 return 120000; } return target[key]; }, set: function(target, key, value) { if (key === "customPrice") { if (val < 100000) { // 最低10萬 throw new Error("價格過低"); } else { target[key] = value; return true; } } } }); console.log(agent.name); console.log(agent.age); console.log(agent.phone); console.log(agent.price); agent.customPrice = 90000; console.log("agent.customPrice", agent.customPrice);
function bindEvent(ele, type, selector, fn) { if (fn === null) { fn = selector; selector = null; } //... } // 調用 bindEvent(elem, "click", "#div1", fn); bindEvent(elem, "click", fn);
class Subject { constructor() { this.state = 0; this.observers = []; } getState() { return this.state; } setState(state) { this.state = state; this.notifyAllObservers(); } notifyAllObservers() { this.observers.forEach(observer => { observer.update(); }); } attach(observer) { this.observer.push(observer); } } // 觀察者模式 class Observer { constructor(name, subject) { this.name = name; this.subject = subject; this.subject.attach(this); } update() { console.log(`${this.name} update state:${this.subject.getState()}`); } } // 測試 let s = new Subject(); let o1 = new Observer("o1", s); let o2 = new Observer("o2", s); let o3 = new Observer("o3", s); s.setState(1);
一、網頁綁定事件
<button id="btn1">btn</button> <script> $("#btn1").click(function() { console.log("1"); }); $("#btn1").click(function() { console.log("2"); }); $("#btn1").click(function() { console.log("3"); }); </script>
二、Promise
function loadImg() { var promise = new Promise(function(resolve, reject) { var img = document.createElement("img"); img.onload = function() { resolve(img); }; img.onerror = function() { reject("圖片加載失敗"); }; img.src = src; }); return promise; } var src = "https://www.baidu.com/static/new.png"; var result = loadImg(src); result .then(function(img) { console.log("width", img.width); return img; }) .then(function(img) { console.log("height", img.height); });
三、jQuery callbacks
var callbacks = $.Callbacks(); callbacks.add(function(info) { console.log("fn1", info); }); callbacks.add(function(info) { console.log("fn2", info); }); callbacks.add(function(info) { console.log("fn3", info); }); callbacks.fire("gogogo"); callbacks.fire("fire");
四、nodejs 自定義事件
(1) EventEmitter
const EventEmitter = require("events").EventEmitter; const emitter1 = new EventEmitter(); emitter1.on("some", function() { // 監聽some console.log("some event is occured 1"); }); emitter1.on("some", function() { // 監聽some console.log("some event is occured 2"); }); emitter1.emit("some");
(2) 基於(1)的應用
const EventEmitter = require("events").EventEmitter; // 繼承 class Dog extends EventEmitter { constructor(name) { super(); this.name = name; } } let simon = new Dog("simon"); simon.on("bark", function() { console.log(this.name, " barked-1"); }); simon.on("bark", function() { console.log(this.name, " barked-2"); }); setInterval(function() { simon.emit("bark"); }, 1000);
(3) 基於(1)的應用
//Stream 用到了自定義事件 var fs = require("fs"); var readStream = fs.createReadStream("./data/file1.txt"); var length = 0; readStream.on("data", function(chunk) { length += chunk.toString().length; }); readSteam.on("end", function() { console.log(length); });
(4) 基於(1)的應用
var readline = require("readline"); var fs = require("fs"); var rl = readline.createInterface({ input: fs.createReadStream("./data/file1.txt") }); var lineNum = 0; rl.on("line", function(line) { lineNum++; }); rl.on("close", function() { console.log("lineNum", lineNum); });
(5)nodejs 中:處理 http 請求;多進程通信
function serverCallback(req, res) { var method = req.method.toLowerCase(); // 獲取請求的方法 if (method === "get") { // 省略三行,上文示例代碼中處理GET請求的代碼 } if (method === "post") { // 接收post請求的內容 var data = ""; req.on("data", function(chunk) { // 一點點 接收內容 data += chunk.toString(); }); req.on("end", function() { // res.writeHead(200, { "Content-Type": "text/html" }); res.write(data); res.end(); }); } }
//parent.js var cp = require("child-process"); var n = cp.for("./sub.js"); n.on("message", function(m) { console.log("Parent got message: " + m); }); n.send({ hello: "world" }); //sub.js process.on("message", function(m) { console.log("child got message: " + m); }); process.send({ foo: "bar" });
(6)vue 和 react 組件生命週期觸發(7)vue watch