navigation

[react] Hooks

[React from zero practice 01- background] code split [React from zero practice 02- background] permission control [React from zero practice 03- background] custom hooks [React from zero practice 04- background] docker-compose Deploy React + Egg +nginx+mysql [React From zero practice 05- background] Gitlab-CI using Docker automated deployment

[source code – Webpack01 – precompiler] AST abstract syntax tree [source code – Webpack02 – Precompiler] Tapable [source code – Webpack03] hand written webpack-compiler simple compilation process [source code] Redux React-redux01 [source] Axios [source] vuex [source -vue01] Data reactive and initialize render [source -vue02] Computed responsive – Initialize, access, Update Procedure [source -vue04] Watch Listening properties – Initialize and update [source -vue04] vue. set and vm.$set [source -vue05] vue.extend

[source -vue06] Vue. NextTick and VM.$nextTick [Deployment 01] Nginx [Deployment 02] Docker deployVUE project [Deployment 03] Gitlab-CI

[Data Structures and Algorithms 01] Binary search and sort

[Deep 01] Execution context [Deep 02] Prototype chain [Deep 03] Inheritance [Deep 04] Event loop [Deep 05] Curri Bias function [Deep 06] Function memory [Deep 07] Implicit conversions and operators [Deep 07] Browser caching mechanism (HTTP caching mechanism) [Deep 08] Front-end security [Deep 09] Deep copy [Deep 10] Debounce Throttle [Deep 10] Front-end routing [Deep 12] Front-end modularization [Deep 13] Observer mode Publish subscribe mode Bidirectional data binding [Deep 14] Canvas [Deep 15] webSocket Webpack HTTP and HTTPS CSS- Interview Handwriting Promise Data Structures and Algorithms – Binary Search and Sorting Js Design Patterns – Agents, policies, singletons

(1) Pre-knowledge

  • Design patterns have been not dare to write, mainly because I think it is easy to understand, mainly timid in the use of production projects

(1) Some words

// Design pattern strategy performance salary salary bonus singletonCopy the code

(2) Storage

  • concept
    • Two objects are deployed: (window.localstorage) and (window.sesstionStorage)
  • methods
    • Storage.setItem(key, value)
      • The key must be a string. Non-strings are converted to strings
      • Value must also be a string; non-strings are converted to strings
      • If the key already exists, the new value overrides the old value
      • This method throws an error if the storage space is full
      • Storage.setitem ('name', 'woow_wu7') is equivalent to storage.name = 'woow_wu7'
    • Storage.getItem(key)
      • If key does not exist, null is returned
    • Storage.removeItem(key)
      • Clear the value corresponding to the key
    • Storage.clear()
      • Example Clear all data in the Storage
      • The return value is undefined
    • Storage.key(number)
      • Take an integer as an argument and return the key for that position
  • The event
    • window.addEventListener('storage', onStorageChange)
    • The event object for the listening function
      • Storageevent. key: Indicates the name of the changed key
      • Storageevent. newValue: new key value, string
      • Storage.oleValue: old key value, a string
      • StorageArea: Returns the entire object
      • Storage.url: Indicates the web address that originally triggered the Storage event.
  • Pay special attention to
    • The event is not triggered on the current page that caused the data change, but on a different window (with the same domain name)
    • So: If your browser has only one window, you may not see this event trigger
    • So: can realize multi-window communication

(3) The command space of the object

var namespace = {
  a: () => { console.log('a') },
  b: () => { console.log('b') },
}
Copy the code

(2) JS design pattern

(1) Agent mode

(1) Definition of proxy pattern

  • Proxy mode: an object is provided and controlled by a proxy object (reference to the original object). The proxy mode is similar to a mediation mode.

(2) Why use the proxy pattern?

  • Mediation isolation
    • (Client object) === (proxy object) === (delegate object)
    • In cases where the client object does not want or cannot refer directly to a delegate object, the proxy object can act as a mediator
  • Open and close principle, add function
    • In addition to being a mediator between the client class and the delegate class, we can add additional functionality to the proxy class to extend the functionality of the delegate class, so that we can directly modify the proxy class rather than the delegate class, in line with the open closed principle of the code design
    • (Proxy class) is mainly responsible for the delegate class (preprocessing messages, filtering messages, forwarding messages to the delegate class, processing the returned results).
    • Instead of providing a service itself, the delegate class provides a specific service by calling the relevant methods of the delegate class. The real business function is implemented by the delegate class

(3) the actual combat

(3-1) Proxy Ajax requests – Added caching

  • role
    • The request() method does a layer of caching by calling cache() via proxyRequest()
    • Cache the parameters for each request. If the parameters are the same, return the cached values in the Map for the previous parameters
  • The principle of
    • To use (proxy pattern) to add new logic to a function of cause without affecting the original function, equivalent to using (function combination) to implement (reuse logic and add logic)
<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, Word-break: break-word! Important; word-break: break-word! Important; word-break: break-word! Important; word-break: break-word! Important; "> <title>Document</title> </head> <body> <script> Mapinstance.get () set() has() delete() clear() const mapInstance = new Map() // request Send a request, Const request = (params) => {return new Promise((resolve, reject) => { setTimeout(() => { return resolve(`data: ${params}`) }, Const cache = (params) => {if (mapinstance.has (params)) {// Map.prototype.has return mapInstance.get(params) // Map.prototype.get } mapInstance.set(params, Const proxyRequest = (params) => {return cache(params)} // If the parameters are the same, Then (data1 => {proxyRequest('11').then(data2 => console.log('data1 === data2? Returns true 'here, data1 = = = data2)}) < / script > < / body > < / HTML >Copy the code

(3-2) Cache proxy – handle cache expiration time – class version

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, Word-break: break-word! Important; "> < div style = "text-align: center;" }) {this.type = type // type this.expires = expires // Expiration time this.storageType = {local: 'localStorage', session: 'sessionStorage'}} // get // proxy native getItem() method, based on cache expiration, GetItem (key) {const now = +new Date() const {value, setTimes } = JSON.parse(window[this.storageType[this.type]].getItem(key)) if (now > setTimes + this.expires) { Window [this.storageType[this.type]].removeItem(key) // save // proxy the native setItem() method, SetItem (key, value) {window[this.storageType[this.type]].setitem (key, json.stringify ({value, setTimes: +new Date() })) } } const localStorage = new Storage({type: 'local', expires: 1000}) localstorage.setitem ('name', 'woow_wu7') console.log(' not expired ', Localstorage.getitem ('name')) setTimeout(() => {console.log(' expired ', localstorage.getitem ('name'))}, 2000) </script> </body> </html>Copy the code

2021/05/03 optimization

(3-2) Optimize cache proxy – handle cache expiration time – class edition

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta http-equiv="X-UA-Compatible" content="IE=edge" /> <meta name="viewport" content="width=device-width, "/> <title>Document</title> </head> <body> <script> class Storage {constructor(type, constructor) expires) { this.storage = window[type]; this.expires = expires; } // save // proxy the native setItem() method, SetItem = (key, value) => {this.storage.setitem (key, json.stringify ({value, setTime: + new Date (), / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - (save) the timestamp})); }; GetItem = (key) => {const now = +new Date(); / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - (take) the timestamp of the const {value, setTime} = JSON. Parse (this. Storage. The getItem (key)); if (now - setTime > this.expires) { this.storage.removeItem(key); / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- expired delete} return this. Storage. The getItem (key); }; } const localStorageInstance = new Storage("localStorage", 5000); localStorageInstance.setItem("name", "woow_wu7"); The console. The log (" has not expired, "localStorageInstance. The getItem (" name")); SetTimeout () = > {the console. The log (" date ", localStorageInstance. The getItem (" name ")); }, 6000); </script> </body> </html>Copy the code

(3-3) Cache proxy – handle cache expiration time – function version

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, Word-wrap: break-word! Important; "> <title>Document</title> </head> <body> <script> Function Storage(type, expires) { this.type = type this.expires = expires this.storageType = { local: 'localStorage', sesstion: 'sesstionStorage' } } Storage.prototype.getItem = function(key) { const now = +new Date() const { value, setTimes } = JSON.parse(window[this.storageType[this.type]].getItem(key)) if (now - setTimes > this.expires) { window[this.storageType[this.type]].removeItem(key) return null } return value } Storage.prototype.setItem = function(key, value) { window[this.storageType[this.type]].setItem(key, JSON.stringify({ value, setTimes: +new Date()}))} const storage = new storage ('local', 1000) store.setitem ('name', 'woow_wu7') console.log(' no expiration ', 'woow_wu7') Storage.getitem ('name')) setTimeout(() => {console.log(' expired ', storage.getitem ('name'))}, 2000) </script> </body> </html>Copy the code

(2) Strategy mode

(1) concept

  • Define a set of algorithms, encapsulate them, and make them interchangeable
  • Separate (the unchanged part) from (the changing part)
  • The main purpose of [strategy pattern] is to separate [algorithm usage] from [algorithm implementation]

(2) Composition – The policy pattern group should contain (policy class) and (environment class)

  • Strategy class
    • Encapsulates the specific algorithm, and is responsible for the specific calculation process
  • The environment class context
    • The context class accepts the request from the client and then delegates the request (delegate) to one of the policy classes
    • A reference to a policy class is maintained in the context class

(3) characteristics

  • Avoid multiple select statements: Strategy pattern utilization (Composition, delegation, polymorphism) can effectively avoid (Multiple conditional selection statements if... else)
  • Conforms to the open and closed principle: encapsulates algorithms in independent strategy strategies, making them easy to switch, understand and extend
  • Algorithm reuse: It can be reused elsewhere in the system to avoid redundant work

(4) shortcomings

  • You must understand all the policies: You must understand the differences between the policies in order to implement a particular policy

(5)

(5-1) Calculate bonus

  • S Performance – 4 times salary
  • A Performance – 3 times salary
  • B Performance – 2 times salary
  • Bonus: the bonus
  • Salary: salary
  • The performance of the performance
  • Strategy: the strategy
  • Strategy Pattern Indicates the strategy pattern
(1) Without any optimization of the writing method - shortcomings - with a lot of if... Else statements - lack of extensibility: To add C performance, you need to modify the internal function implementation, Function getBonus(Performance, Salary) {// Bonus bonus performance bonus if (performance === 'S') return 4 * salary; if ( performance === 'A') return 3 * salary; if ( performance === 'B') return 2 * salary; } bonus ('S', 1000) // Output: Function getS (salary) {return 4 * salary} function getA (salary) {return 3  * salary } function getB (salary) { return 2 * salary } function getBonus(performance, salary) { if ( performance === 'S') return getS(salary) if ( performance === 'A') return getA(salary) if ( performance === 'B') return getB(salary)} bonus ('S', 1000) 4000 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- (3) use the strategy pattern strategyPattern - refactor the code - advantages - eliminates a lot of the if... Else statement - All the logic for calculating bonus is not in the getBonus function, the environment class context, but in the strategy object. - Context environment class is not responsible for calculating, Const strategy = {S: (salary) => 4 * salary, A: (salary) => 3 * salary, B: (salary) => 4 * salary, A: (salary) => 3 * salary, B: (salary) => 2 * salary, } const getBonus = (performance, salary) => strategy[performance](salary) getBonus('S', 1000) // Output: 4000Copy the code

(5-2) Form validation

  • The unoptimized code is as follows
(1) The unoptimized code is <! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, "> <title>Document</title> </head> <body> <form action="javascript:void(0)" method="post"> <input <input type="password" name="password"> <button> Form submission </button> </form> <script> const form = Document.queryselector ('form') form.onSubmit = () => {// form.username can access the input element node if name="username" (form. The username. Value = = = ' ') {the console. The log (' user name cannot be empty) return false} the if (form. The password. The value. Length < 6) { Return false}} </script> </body> </ HTML >Copy the code
  • Use the policy pattern - optimize expression validation
    • Step 1: Encapsulate the validation logic (in the policy object Strategy)
    • Step 2: Delegate the user’s request (context object) to the strategy object to handle the request
(2) Using the policy pattern - optimized expression verification <! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, "> <title>Document</title> </head> <body> <form action="javascript:void(0)" method="post"> <input Type ="text" name="username"> <input type="password" name="password"> <button> Form submission </button> </form> <script> policy object // 1. Here each method can take (two) or (three) // 2. // - "isEmpty".split('; ') => ["isEmpth"].shift() => [].unshift(value) => [value].push(err) => [value, err] // - "minLength:6".split(";" ) = > [r]. "minLength", "6" shift () = > [' 6 '] unshift (value) = > [value, '6']. Push (err) = > [value, '6', err] / / - is the last two cases: [value, err] or [value, minLength, err] / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- strategys const strategys = {notEmpty: (value, err) => { if (value === '') return err }, minLength: (value, minLength, err) => { if (value.length < minLength) return err }, } / / environmental context / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the Validator class Validator {constructor () {this. Rules = [] / / Array of rules, } add = (dom, rule, err) => {const ruleToArr = rule-.split (':') // ['isEmpty'] or ['minLength', 6] this.rules.push(() => {const strategy = ruleToarr.shift () // 'isEmpty' or 'minLength' Ruletoarr. push(err) return strategys[strategy].apply(null, RuleToArr = [value, err] or [value, minLength, err]})} start = () => {for(let I = 0; i < this.rules.length; Let err = this.rules[I](); let err = this.rules[I](); If (err) {return err}}}} / / -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the form element node const form = document.querySelector('form') form.onsubmit = (e) => { e.preventDefault() const validator = new Validator() Add (form.username, 'notEmpty', 'username cannot be null ') // Add validator.add(form.password, 'minLength:6', // add const err = validator.start() // start if (err) {console.log('err', err) return false } } </script> </body> </html>Copy the code

(3) Singleton pattern

(1) the definition

  • Ensure that there is only one instance of a class and provide a global point of access to it
  • advantages
    • (creating objects) and (managing singletons) are distributed in different methods

(2) Application scenario

  • The global variable
  • Connect to the database to prevent multiple connections or disconnections
  • Global state management Redux vuex
  • Login box, form, loading layer, etc

(3) implementation

(3-1) The closure implements a singleton

  • Disadvantages: You need to call the getInstance function to create the object
Function Singleton(name) {// constructor, Singleton: Single, note: Arrow functions cannot be used as constructors, arguments, Yeild command this.name = name} Singleton. GetInstance = (() => {let instance = null return (name) => {if (! instance) { instance = new Singleton(name) } return instance } })(); // the IIFE function expression is called immediately. Const a = singleton.getInstance ('a ') const b = singleton.getInstance ('a ') const b = singleton.getInstance (' b ' b', a === b) // trueCopy the code

The (3-2) function implements a singleton

  • Disadvantages: You need to call the getInstance function to create the object
Function (name) {this.name = name} Singleton. GetInstance = function(name) {// note: // 1. This refers to the Singleton, not to the instance if (! this.instance) { this.instance = new Singleton(name) } return this.instance } const a = Singleton.getInstance('A') const  b = Singleton.getInstance('B') console.log('a === b', a === b) console.log('a', a) console.log('b', B) console.log('Singleton. Instance ', 'Singleton. Instance 'Copy the code

(3-3) Transparent singleton pattern

  • Advantage: Solves the problem in 12 where you need to call createInstance to generate the object, which is called directly by new
  • Disadvantages: Not conforming to the single responsibility principle, this object is actually responsible for two functions: singletons and create objects
var Singleton = (function() { var instance = null return function(name) { if (instance) return instance this.name = name Return instance = this // return the instance object, instance is only for judgment}})(); // IIFE return const a = new Singleton(' a ') const b = new Singleton(' b') console.log('a === b', 'a === b', a === b) console.log('a', a)Copy the code

(3-4) ES6 implementation singleton

class Book { constructor(name) { if (! Book.intance) { this.name = name Book.intance = this } return Book.intance } } const english = new Book('english') const  chinese = new Book('chinese') console.log('english === english', english === english) console.log('english', english) console.log('chinese', chinese)Copy the code

(4) Actual combat – login box

<! DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, Initial =1.0"> <title>Document</title> </head> <body> <button id="login"> </button> <script> function init() { const button = document.getElementById('login') button.addEventListener('click', showModal, Var instance = (() => {var instance = null return function(fn) {if (! Function createModal() {const div = const div = function createModal() Document.createelement ('div') div.innerHTML = 'landing box' div.style.setProperty('width', '300px') div.style.setProperty('height', '300px') div.style.setProperty('border', '1px solid black') document.body.appendChild(div) return div } function showModal() { singleton(createModal) } </script>  </body> </html>Copy the code

data

  • Proxy mode juejin.cn/post/684490…
  • Policy Mode 1 juejin.cn/post/684490…
  • Policy Mode 2 juejin.cn/post/684490…
  • Singleton pattern A juejin.cn/post/684490…
  • Singleton pattern B juejin.cn/post/689451…