navigation

[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

[react] Hooks

[Deployment 01] Nginx [Deployment 02] Docker deployVue project [Deployment 03] gitlab-CI

[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 initial render

Front knowledge

The stack

  • Stack stack
    • The stack contains the identifier of the variable and the value of the variable
    • The stack area:
      • Refers to stack memory in memory
      • Data of the basic type (value type data) is stored in the stack
    • To compare
      • A comparison of basic type data is a comparison of values
      • Basic type data (immutable), can not add properties and methods
  • Heap heap
    • The heap area
      • Reference type data is stored in the stack and heap
      • Stack stores: variable identifiers and Pointers to objects in heap memory
      • The heap holds: specific object data
    • To compare
      • A comparison of reference type data is a comparison of (references)
      • Reference type data (mutable), properties and methods can be added

The data type

  • Basic data types (value types) : Number, string, Boolean, NULL, undefined, symbol
  • Reference data of type: object, array, function, etc
  • The difference between:
    • Basic types have no properties or methods, are fixed in size, and are stored in the stack
    • Reference types have properties and methods of varying sizes and are stored in the stack area and the heap area, with the stack holding the address to the data in the heap

Data type cases

Var a = 1 var b = {name: 'woow_wu7'} var aa = a // a and aa are different data var bb = b // b and bb refer to the same data in the heap, modify the data in the heap, b and bb refer to the same data, A = 2 b.name = 'wang' console.log(a, aa, 'a and aa are different data ') Console. log(b === bb) console.log(b === bb) console.log(b === bbCopy the code

Map data structure

  • Object The key of an Object can only be a string
    • String valueThe corresponding
  • The key of the Map data structure can be of any type
    • Value -The corresponding
  • A Map is like an object. It is also a collection of key and value pairs
  • Map is a more sophisticated implementation of the hash structure. If you need a data structure for key-value pairs, Map is better than Object
  • Map.prototype.set(key, value) // The key can be of any type
  • Map.prototype.get(key)
  • Map.prototype.has(key) // Returns a Boolean value
  • Map.prototype.delete(key) // Deletes a key, but returns a Boolean value to indicate whether the key is successfully deleted
  • Map.prototype.clear() // Clear all members, no return value
  • Map.prototype.keys() values() entries() forEach()
  • The Map constructor can take arrays as arguments. The members must be arrays representing key-value pairs
  • Map ensures that the key of an object is unique
Const mapArrKey = [1, 2]; New Map([['name', 'woow_wu'], [[1,2], 20], [mapArrKey, 20], [{age: 20}, {age: 20}], ]) console.log(mapInstance, 'mapInstance') console.log(mapInstance.size, 'size') // 4 console.log(mapInstance.get(mapArrKey), 'map.prototype.get (key) => key is an array ') console.log(mapinstance.get ([1,2]), 'map.prototype.get (key)') // undefined must be the same array mapinstance.set (mapKeyAddress, Log (mapinstance.get (mapKeyAddress)) console.log(mapinstance.has (mapKeyAddress)) 'map.prototype. has(key) => Whether the key exists, // true console.log(mapinstance.delete (mapKeyAddress), 'map.prototype.delete (key) => delete key, return Boolean, Log (mapinstance.get (mapKeyAddress)) // undefined console.log(mapinstance.clear (), 'map.prototype. clear() => delete all keys, no return value ') console.log(mapInstance)Copy the code

Reflect

  • API for manipulating objects
  • -sheldon: And reflects on me
  • Reflect.get(target, name, receiver)
    • Gets the name attribute of the target object, and returns undefined if it does not have the attribute
    • If the name property has a getter function deployed, the this in the getter refers to the Receiver parameter object
    • If the target argument is not an object, reflect.get () will report an error
  • Reflect.set(target, name, value, receiver)
    • Set the name attribute of the target object to value
    • If the name property has a settter function deployed, the this in the setter refers to the Receiver parameter object
  • Reflect.deleteProperty(obj, name)
    • Delete the name attribute of obj
    • Delete obj.name
  • Reflect.constructor(target, args)
    • We execute the target constructor, passing args as an argument to the target constructor
    • If target is not a function, an error is reported
  • Reflect.getPrototypeOf(obj)
    • Equals: object.getprototypeof (obj)
  • Reflect.setProrotypeOf(obj, prototypeObj)
  • Reflect.apply(func, thisArg, args)
    • Is equal to: the Function prototype. Apply. Call (func, thisArg, arges)
  • Reflect.ownKeys(target)
    • Returns all the properties of the object parameter, including the properties of type Symbol
    • Equal to the Object. GetOwnPropertyNames and Object. GetOwnPropertySymbols combined
    • Include properties of type symbol!!

Operator associativity

  • Unary operators, ternary operators, assignment operators are right associative, and all the others are left associative
  • Ternary operators are right associative: that is, they work from right to left, first counting the ternary expression on the right and then the ternary expression on the left
Let name = null 1 === true? name = 'wang' : 1 < 0 ? name = 'zhang' : name = 'woow_wu7'; // Equivalent to: 1 === true? name = 'wang' : (1 < 0 ? Name = 'zhang' : name = 'woow_wu7') console.log(name, 'name') // 'woow_wu7' // 1 === true // falseCopy the code

Typeof return value

  • Typeof can be used to determine the basic data type and the return value is a string
  • Typeof does not distinguish between data of an object type, such as an object or an array
  • There are seven types of return values of Typeof
Typeof - return values (7) : number, string, Boolean, undefined, symbol, function, object - based data type (6) : number,string,boolean,undefined,symbol,null typeof NaN ---------------------- 'number' typeof Symbol() -----------------  'symbol' typeof function(){} ------------- 'function' typeof [] ---------------------- 'object' typeof {} ---------------------- 'object' typeof null --------------------- 'object'Copy the code

The difference between shallow and deep copies

  • A shallow copy copies only one level of data, and a deep copy copies all levels until the corresponding value of an attribute is the original data
  • Shallow copy
    • Create a new object (creating a new heap space) that has an exact copy of the original object’s property values
    • The value of the property is the basic type, and the copy is the value of the basic type (That is, copy is the value, do not interfere with each other)
    • The property value is a reference type, and the copy is a pointer to the heap memory (It's a copy of the pointer, interfering with each other)
  • Deep copy
    • Create a new space in the heap memory and copy the completed objects to the new space independently of each other

The difference between shallow copy and assignment

It is difficult to distinguish between shallow copy and assignment because copy is usually followed by assignment

  • Assignment: Pointers to two variable objects that point to object data in the same heap memory and do not create new heap space
  • Shallow copy: Create a new heap memory space (that is, create a new object). The new object is an exact copy of the original object. If the property is a value of the primitive type, the copy is a pointer to the heap memory
  • In one sentence:

    (1) Assignment does not create new heap memory space, while shallow copy does; (2) Assignment: change the object attributes to influence each other; (3) Shallow copy: when the attribute value is the original type, each other does not interfere. Changing attribute values when they are reference types affects each other

Example of the difference between assignment and shallow copy

Var a = {name: 'woow_wu', score: {ch: 90, en: 80}}; var b = a var c = {... A} console.log(a===b, 'assignment => create new heap space, ') console.log(a===c,' shallow copy => create new heap space, 'modify the original value attribute without disturb each other, A.name = 'wang' console.log(b, 'b') // interact console.log(c, 'c => shallow copy, En = 100 console.log(c, 'c => shallow copy, change the attribute value to reference type => Mutual influence ') // Mutual influenceCopy the code

Shallow copy

Object

  • Object.assign()
  • {… } expansion operator

Array shallow copy

  • Array.prototype.slice() / / not to participate
  • Array.prototype.concat() / / not to participate
  • […]. Expansion operator
Const arr = [1, 2, 3] - 1 slice - slice (start, end) - part of the intercept the target array, -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- (returns a new array, -start = 0; -end = 0; // arr. Slice (0, 2) // [1, 2] -arr. Slice (0, 1) -arr. Slice (0, 2) -arr. 2. Concat - concat - is used to merge multiple arrays. It adds the members of the new array to the end of the original array, ---- (returns a new array, Concat's arguments can be any type of value other than (array) 3. -arr.concat () // without arguments -arr.slice () // without arguments - [...arr]Copy the code

Deep copy

Methods a JSON. Parse (JSON. Stringify ())

  • Disadvantages:
  • Only deep copy objects and arrays, but not functions, circular references, properties and methods on the prototype chain (Date, RegExp, Error, etc.)
const objComplex = { name: 'woow_wu7', address: { city: 'chongqing', district: 'yubei', town: 'jiazhou', detail: [' chongqing ', 'yubei', 'jiazhou]}, arr: [1, 2, {30} l: 20, r:], fn: function () {}, / / the function date: new Date(), // Date err: new Error(), // Error reg: new RegExp(), // RegExp number: 1, string: '', boolean: true, null: null, undefined: undefined, symbol: Symbol('symbol'), // Symbol } const copy = JSON.parse(JSON.stringify(objComplex)) console.log(objComplex, Json.parse (json.stringify ()) cannot copy function, Date, Error, RegExp, etcCopy the code

Method 2

Basic edition – for… In loop recursion (1)

  • Requirement: You can copy objects and arrays
  • Unresolved:
    • A circular reference
    • A copy of the value of the key attribute of type Symbol()
    • Copy other objects such as Date, Error, Regexp, Symbol data types, etc
const objComplex = { name: 'woow_wu7', address: { city: 'chongqing', district: 'yubei', town: 'jiazhou', detail: ['chongqing', 'yubei', 'jiazhou'] }, score: [100, 200] } function deepClone(parameter) { const parameterType = Object.prototype.toString.call(parameter).slice(8, // array.prototype.slice (8, -1); // Array.prototype.slice(8, -1); Const cloneObj = null; // const cloneObj = null; // Const cloneObj = null; // Const cloneObj = null; If (parameterType === 'Array') {cloneObj = []} else if (parameterType === 'Object') {cloneObj = {}} else { return parameter } for(let key in parameter) { // for... In // 1. Loop is used to traverse the object (all traversable properties), will (skip the non-traversable properties) // 2. Not only can you iterate over (own properties), but also (inherited properties) // 3. So in general, (for... If (parameter.hasownProperty (key)) {if (typeof parameter[key] === 'object') {if (parameter [key] === 'object') { // Object or array, continue to determine // the use of typeof is not to range is a score group or object, CloneObj [key] = deepClone(parameter[key])} else {// typeof is not objet Number string Boolean undefined symbol function cloneObj[key] = parameter[key]}}} return cloneObj } const res = deepClone(objComplex) console.log(res, 'res')Copy the code
Const obj = {name: 'woow_wu7', address: {city: 'chongqing', districe: 'yubei', town: 'jiazhou', detail: ['chongqign', 'yubei', 'jiazhou'] }, arr: [1,2]} function deepClone(parameter) {if (typeof parameter === 'object') { // Number string Boolean undefined symbol Function object const objClone = array.isarray (parameter)? [] : {} for (let key in parameter) { if (parameter.hasOwnProperty(key)) { objClone[key] = deepClone(parameter[key]) // DeepClone (parameter[key]) is used to determine whether the object type is an array or an object. ObjClone [key]}} return objClone} else {// Return parameters that are not arrays or objects // Note that the parameter is a newly declared variable return parameter}} const res = deepClone(obj) console.log(obj) console.log(res)Copy the code

Map resolve circular references – for… In loop recursion (2)

  • Requirements: You can copy objects and arrays and resolve circular references
(1) What is a circular reference? Const obj = {name: 'wang'} obj. Circle = obj const obj = {name: 'wang'} obj. In loop deepClone(parameter[key]) repeats over and over again ---------- (2) 1. Check whether there are cloned objects in the map instance. 2. Var objComplex = {address: {city: 'Chongqing ', town: 'jiazhou',}, score: [100, 200],} objcomplex.circular = objComplex function deepClone(objComplex, mapx = new Map()) { Is an empty map instance if (Typeof objComplex! == 'object') {// Return objComplex if not object and Array} const objClone = array.isArray (objComplex)? [] : If (mapx.get(objComplex)) {return mapx.get(objComplex)} if (mapx.get(objComplex)) {return mapx.get(objComplex)} Set (objComplex, objClone) for(let key in objComplex) {objClone[key] = deepClone(objComplex[key], Mapx) // Note: Mapx calls deepClone() regardless of objComplex[key] type, } return objClone} const res = deepClone(objComplex) console.log(res, 'res')Copy the code

Reflect.ownkeys () loop recursion (3)

  • Requirements: can copy objects and arrays, resolve circular references, and resolve Symbol data types
  • Solve the Symbol data type
  • Symbol cannot be called with new. The parameter can be an array
  • Reflect.ownkeys (obj) returns all properties of the parameter object itself, including the properties of the symbol data type
    • If the argument is not obj, typeError is raised
    • Disadvantages: Reflect cannot take properties and methods on the prototype chain
Var objComplex = {address: {city: 'chongqing', town: 'jiazhou',}, score: [100, 200], } objComplex.circular = objComplex objComplex[Symbol()] = 'symbol' function deepClone(objComplex, mapx = new Map()) { if (typeof objComplex ! == 'object') { return objComplex } const objClone = Array.isArray(objComplex) ? [] : {} if (mapx.get(objComplex)) { return mapx.get(objComplex) } mapx.set(objComplex, objClone) // for(let key in objComplex) { // objClone[key] = deepClone(objComplex[key], mapx) // } Reflect.ownKeys(Array.isArray(objComplex) ? [...objComplex] : { ... ObjComplex}).foreach (key => {// reflect.ownKeys (obj) return all properties of object arguments, ObjClone [key] = deepClone(objComplex[key], mapx) }) return objClone } const res = deepClone(objComplex) console.log(res, 'res')Copy the code
  • 2021/06/20 optimization
  • In the ownKeys argument above, there is no need to determine whether the ownKeys is an array, because ownKeys can iterate through arrays and objects
<script> // deep clone const obj = { name: "woow_wu7", address: { city: "chongqing", districe: "yubei", town: "jiazhou", detail: ["chongqign", "yubei", "jiazhou"], }, arr: [1, 2], [Symbol("unique")]: "unique", }; obj.circle = obj; const deepClone = (param, map = new Map()) => { let typeParams = Object.prototype.toString.call(param); if (typeof param ! == "object" && typeof param ! == "function") { return param; } if (map.get(param)) { return map.get(param); } let resObj = Array.isArray(param) ? [] : {}; map.set(param, resObj); // for (let key in param) { // resObj[key] = deepClone(param[key], map); } reflect.ownkeys (param).foreach ((key) => {resObj[key] = deepClone(param[key], map);} Reflect.ownkeys (param).foreach ((key) => {resObj[key] = deepClone(param[key], map); }); return resObj; }; const newObj = deepClone(obj); newObj.name = "222"; console.log(`newObj`, newObj); console.log(`obj`, obj); </script>Copy the code

Structured cloning algorithm for Copying other objects (4)

  • Requirements: can copy objects and arrays, and solve circular reference problems (Map caching), and solve Symbol data type (refly.ownkeys ()), solve other objects copy (structured cloning), constructor to generate instances of the prototype object copy
  • For example, Date, Regexp, a copy of the properties of the prototype object for the instance generated by the constructor
  • Disadvantages: Can’t handle errors, can’t handle functions, can’t handle DOM nodes
function Message() { this.sex = 'man' } Message.prototype.age = 1000 var objComplex = { address: { city: 'chongqing', town: 'jiazhou', }, score: [100, 200], [Symbol()]: 'symbol', date: new Date(), reg: new RegExp(), fn: function () { }, err: new Error(), message: new Message() } objComplex.circle = objComplex function deepClone(objComplex, mapx = new Map()) { if (typeof objComplex ! == 'object') { return objComplex } let objClone = Array.isArray(objComplex) ? [] : {} if (mapx.get(objComplex)) { return mapx.get(objComplex) } mapx.set(objComplex, objClone) // for(let key in objComplex) { // objClone[key] = deepClone(objComplex[key], mapx) // } // Reflect.ownKeys(Array.isArray(parameter) ? [...parameter] : { ... parameter }).forEach(key => { // objClone[key] = deepClone(parameter[key], Mapx) //}) switch (objcomplex.constructor) {case Date: case RegExp: case Message: case Date: case RegExp: case Message: case Date: case RegExp: case Message: ObjClone = new objcomplex.constructor (objComplex) break // If there is a request for the Date, RegExp, or Message constructors // generate instances with these constructors, respectively. Default: reflect.ownKeys (array.isarray (objComplex)? [...objComplex] : {... objComplex}).forEach(key => { objClone[key] = deepClone(objComplex[key], mapx) }) } return objClone } const res = deepClone(objComplex) console.log(res, 'res') console.log(res.message.age, 'Cloned object ') console.log(objcomplex.message.age,' original object ')Copy the code

2021/07/17 review

<! 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, Initial-scale =1.0" /> <title>Document</title> </head> <body> <script> // deepClone // 1 Symbol() data type => reflect.ownKeys () // 3. < span style = "box-sizing: border-box; color: RGB (50, 50, 50); word-break: inherit! Important;" Const obj = {num: 1, STR: "STR ", boo: true, und: undefined, [Symbol()]: Symbol(), arr: [1, 2, 3], obj: const obj = {num: 1, STR:" STR ", boo: true, und: undefined, [Symbol()]: Symbol(), arr: [1, 2, 3], obj: { name: "woow_wu7" }, date: new Date(), regexp: new RegExp(), }; obj.circle = obj; const deepClone = (params, map = new Map()) => { if (typeof params ! == "object") { return params; } let resObj = Array.isArray(params) ? [] : {}; if (map.get(params)) { return map.get(params); } map.set(params, resObj); // for (let key in params) { // if (params.hasOwnProperty(key)) { // resObj[key] = deepClone(params[key], map); // } // } // Reflect.ownKeys(params).forEach(key => { // resObj[key] = deepClone(params[key], map) // }) switch (params.constructor) { case Date: case RegExp: resObj = new params.constructor(params); break; default: Reflect.ownKeys(params).forEach((key) => { resObj[key] = deepClone(params[key], map); }); break; } return resObj; }; const res = deepClone(obj); console.log(`res`, res); console.log(`obj`, obj); </script> </body> </html>Copy the code

Basic: juejin. Cn/post / 684490… Deep: juejin. Cn/post / 684490… Zhihu (lodash deepClone source code analysis) : zhuanlan.zhihu.com/p/41699218 stack, heap:segmentfault.com/a/119000000… Juejin. Cn/post / 684490… My Jane books www.jianshu.com/p/a2306eba0…