• Write a call
Function.prototype.myCall = function(thisArg, ... Args) {const fn = Symbol (' fn ') / / declare a unique Symbol of property, prevent the fn thisArg = from the existing attributes thisArg | | the window / / if no to this, ThisArg [fn] = thisArg[fn] = thisArg[fn] = thisArg[fn] = thisArg Args) // Execute the current function delete thisArg[fn] // delete the fn property we declared return result // test foo.mycall (obj)Copy the code
  • Handwritten apply
Function. The prototype. MyApply = Function (thisArg, args) {const fn = Symbol (' fn ') / / declare a unique Symbol of property, Prevent fn thisArg = from the existing attributes thisArg | | the window / / if no to this, ThisArg [fn] = thisArg[fn] = thisArg[fn] = thisArg[fn] = thisArg Args) // Execute the current function delete thisArg[fn] // delete our declared fn attribute return result // Test foo.myapply (obj, [])Copy the code
  • Write a bind
Function.prototype.myBind = function (thisArg, ... Args) {var fbound = function () {self.apply(this instanceof self? this : thisArg, Args. Concat (Array) prototype. Slice. The call (the arguments)))} / / inherit the properties and methods fbound on the prototype. The prototype = Object. The create (self. The prototype); return fbound; } // test const obj = {name: } function foo() {console.log(this.name) console.log(arguments)} foo.mybind (obj, 'a', 'b', 'c')()Copy the code
  • Image stabilization
function debounce(func, wait) {
    let timeout = null
    return function() {
        let context = this
        let args = arguments
        if (timeout) clearTimeout(timeout)
        timeout = setTimeout(() => {
            func.apply(context, args)
        }, wait)
    }
}
Copy the code
  • The throttle
function throttle(func, wait) { let timeout = null return function() { let context = this let args = arguments if (! timeout) { timeout = setTimeout(() => { timeout = null func.apply(context, args) }, wait) } } } function throttle(func, wait) { var prev = 0; return function() { let now = Date.now(); let context = this; let args = arguments; if (now - prev > wait) { func.apply(context, args); prev = now; }}}Copy the code
  • Implement new
New Foo(args) <=> myNew(args) function myNew(Foo, args)... // Create a new object and inherit the constructor's prototype property. This step is to attach obj to the prototype chain. Prototype let obj = object.create (foo.prototype) // execute constructor and bind new this to it, Let result = foo.apply(obj, obj, obj, obj, obj, obj, obj, If the constructor has already returned an object, it returns that object. Normally, the constructor does not return a new instance. Return typeof result === 'object' && result! Return typeof result === 'object' && result! == null ? result : obj } function Foo(name) { this.name = name } const newObj = myNew(Foo, 'zhangsan') console.log(newObj) // Foo {name: "zhangsan"} console.log(newObj instanceof Foo) // trueCopy the code
  • inheritance
function Parent(name) { this.name = [name] } Parent.prototype.getName = function() { return this.name } function Child() {// The constructor inherits parent-call (this, 'zhangsan')} // Child. Prototype = new Parent() Child. Prototype = object.create (Parent. / / will ` points to the parent class instance ` ` instead point to the parent class prototype ` Child. The Child/prototype. The constructor = / testing const Child Child () = new const parent = new parent () child.getName() // ['zhangsan'] parent.getName()Copy the code

jsonp

/** * Write jSONp and return Promise object * parameter URL, data:json object, */ function jsonp(url, data = {}, callback = 'callback') { Callback = callback let params = [] for (let key in data) {params.push(key + '=' + data[key])} Console. log(params.join('&')) // Create a script element let script = document.createElement('script') script.src = url + '? '+ params. Join (' &') document. The body. The appendChild (script) / / return promise return new promise ((resolve, Reject) => {window[callback] = (data) => {try {resolve(data)} catch (e) {reject(e)} finally {// Remove script elements script.parentNode.removeChild(script) console.log(script) } } }) } jsonp('http://photo.sina.cn/aj/index', { page: 1, cate: 'recommend' }, 'jsoncallback').then(data => { console.log(data) })Copy the code

ajax promise

function getJson(url) { let promise = new Promise((resolve, reject) => { let xhr = new XMLHttpRequest() xhr.open('GET', url, true) xhr.onreadystatechange = function() { if (this.readyState ! == 4) return if (this.status === 200) { resolve(this.response) } else { reject(new Error(this.statusText)) } } xhr.onerror = function() { reject(new Error(this.statusText)) } xhr.responseType = 'json' xhr.setRequestHeader('Accept',  'application/json') xhr.send(null) }) return promise }Copy the code

Deep copy

if(obj.constructor === Date) return new Date(obj);

if(obj.constructor === RegExp) return new RegExp(obj)

let obj ={ a: 15, b: 2, c: { d:1, e:3, fn: function(){ console.log(1111111111111) }, date: new Date(), reg: new RegExp(/^\d+$/g) } } function deepClone(obj) { let map = new WeakMap() function dc(obj) { let res, exitObj if (obj.constructor === Date) { return new Date(obj) }else if (obj.constructor === RegExp) { return new RegExp(obj) }else if (Array.isArray(obj)) { res = [] } else if (Object.prototype.toString.call(obj) === '[object Object]'){ res = {} }else{ return obj } exitObj = map.get(obj) if (exitObj) { return exitObj } map.set(obj, Res) for (let key in obj) {if (obj. HasOwnProperty (key)) {//symbol change to Reflect. OwnKeys if (obj[key] && typeof obj[key] === 'object'){ res[key] = dc(obj[key]) }else{ res[key] = obj[key] } } } return res } return dc(obj) } let res = deepClone(obj) res.a = 5555 console.log(obj) console.log(res)Copy the code

Depth-first and breadth-first traversal

  • In a nutshell, depth-first is a top-down traversal and breadth-first is a layer-by-layer traversal, as shown below

Depth first

breadth-first

For an algorithm it’s just time for space space for time

  1. Depth-first does not need to remember all nodes, so it takes up small space, while breadth-first requires that all nodes take up large space
  2. Depth-first operations have backtracking (there is no way to go back) so the time is relatively longer

Depth-first takes the form of a stack, which is first in, last out

Breadth first takes the form of a queue, i.e., first-in, first-out

const data = [ { name: 'a', children: [ { name: 'b', children: [{ name: 'e' }] }, { name: 'c', children: [{ name: 'f' }] }, { name: 'd', children: [{ name: 'g' }] }, ], }, { name: 'a2', children: [ { name: 'b2', children: [{ name: 'e2' }] }, { name: 'c2', children: [{ name: 'f2' }] }, { name: 'd2', children: [{ name: Function getName(data) {const result = []; function getName(data) {const result = []; data.forEach(item => { const map = data => { result.push(data.name); data.children && data.children.forEach(child => map(child)); } map(item); }) return result.join(','); Function getName2(data) {let result = []; function getName2(data) {let result = []; let queue = data; while (queue.length > 0) { [...queue].forEach(child => { queue.shift(); result.push(child.name); child.children && (queue.push(... child.children)); }); } return result.join(','); } console.log(getName(data)) console.log(getName2(data))Copy the code

promise

class Promise{ constructor(executor){ this.state = 'pending'; this.value = undefined; this.reason = undefined; this.onResolvedCallbacks = []; this.onRejectedCallbacks = []; let resolve = value => { if (this.state === 'pending') { this.state = 'fulfilled'; this.value = value; this.onResolvedCallbacks.forEach(fn=>fn()); }}; let reject = reason => { if (this.state === 'pending') { this.state = 'rejected'; this.reason = reason; this.onRejectedCallbacks.forEach(fn=>fn()); }}; try{ executor(resolve, reject); } catch (err) { reject(err); } } then(onFulfilled,onRejected) { onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value; onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err }; let promise2 = new Promise((resolve, reject) => { if (this.state === 'fulfilled') { setTimeout(() => { try { let x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); }}, 0); }; if (this.state === 'rejected') { setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); }}, 0); }; if (this.state === 'pending') { this.onResolvedCallbacks.push(() => { setTimeout(() => { try { let x = onFulfilled(this.value); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); }}, 0); }); this.onRejectedCallbacks.push(() => { setTimeout(() => { try { let x = onRejected(this.reason); resolvePromise(promise2, x, resolve, reject); } catch (e) { reject(e); }}}, 0)); }; }); return promise2; } catch(fn){ return this.then(null,fn); } } function resolvePromise(promise2, x, resolve, reject){ if(x === promise2){ return reject(new TypeError('Chaining cycle detected for promise')); } let called; if (x ! = null && (typeof x === 'object' || typeof x === 'function')) { try { let then = x.then; if (typeof then === 'function') { then.call(x, y => { if(called)return; called = true; resolvePromise(promise2, y, resolve, reject); }, err => { if(called)return; called = true; reject(err); }) } else { resolve(x); } } catch (e) { if(called)return; called = true; reject(e); } } else { resolve(x); } //resolve = function(val){return new Promise((resolve,reject)=>{resolve(val)}); Reject = function(val){return new Promise((resolve,reject)=>{reject(val)}); Return Promise((resolve,reject)=>{for(let I =0; i<promises.length; i++){ promises[i].then(resolve,reject) }; // promise. All = function(promises){let arr = []; let i = 0; function processData(index,data){ arr[index] = data; i++; if(i == promises.length){ resolve(arr); }; }; return new Promise((resolve,reject)=>{ for(let i=0; i<promises.length; i++){ promises[i].then(data=>{ processData(i,data); },reject); }; }); }Copy the code

Flat array sort

let arr = [ [1, 2, 2], [3, 4, 5, 5], [6, 7, 8, 9, [11, 12, [12, 13, [14] ] ] ], 10] arr.toString().split(',').sort((a,b)=>a-b).map(Number) while(arr.some(item => Array.isArray(item))) { arr = [].concat(... arr) }Copy the code

Array to object

Const arr = [{username: 'makai', displayName: 'curator ', email: '[email protected]'}, {username: 'Xiaoer ', displayName: 'xiaoer', email: '[email protected]'}, {username: 'zhanggui', displayName:' owner ', email: null }, ]; Function callback(acc, person) {function callback(acc, person) { // Return a new object with a new attribute {... acc, [person.username]: person}; } const obj = arr.reduce(callback, {}); // The initial value here is {} console.log(obj);Copy the code

A comma for three floating point numbers

function format(number){ if(number.indexOf('.') == -1) { return number.replace(/\B(? =(\d{3})+$)/g, ',') } else { return number.replace(/\B(? =(\d{3})+.) /g, ',') } }Copy the code

Observer model

class Subject{ constructor(arg) { this.observers = [] } add(observer) { this.observers.push(observer) } notify(... args) { this.observers.forEach(item => item.update(... args)) } } class Observer { update(... args) { console.log(... args) } } let sub = new Subject() let observer1 = new Observer() let observer2 = new Observer() sub.add(observer1) sub.add(observer2) sub.notify('4564')Copy the code

The tree menu

Let arr = [{id: 1, name: guangdong, pid: 0}, {id: 2, name: guangzhou, pid: 1}, {id: 3, name: 'the tianhe, pid, 2}, {id: 4, name: 'white cloud', pid: 2}, {id: 5, name: 'in guangxi, pid: 0}, {id: 6, name: yulin, pid, 5}, {id: 7, name:' north flow, pid: 6}, {id: 8, name: shenzhen, pid: 1}, {9, id: name: dongguan, pid: 1}, {id: 10, name: 'songshan lake, pid: 9}, ] function getMenu(data) { let ans = [] let map = new WeakMap() if (data && data.length) { data.forEach(item => map[item.id] = item) data.forEach(menu => { let parent = map[menu.pid] if (parent) { parent.chidlren = parent.chidlren | | [] parent. Chidlren. Push (menu)} else {/ / is a top ans. Push (menu)}})} return ans} the console. The log (getMenu (arr))Copy the code

Array lookup path

const data = [ { name: 'a', children: [ { name: 'b', children: [{ name: 'e' }] }, { name: 'c', children: [{ name: 'f' }] }, { name: 'd', children: [{ name: 'g' }] }, ], }, { name: 'a2', children: [ { name: 'b2', children: [{ name: 'e2' }] }, { name: 'c2', children: [{ name: 'f2' }] }, { name: 'd2', children: [{ name: 'g2' }] }, ], } ] function fn(data, name, path) { if (! path) path = [] for(let i =0; i<data.length; i++) { let item = data[i] let temp = [...path] temp.push(item.name) if (item.name === name) return temp if (item.children) { let res = fn(item.children, name, temp) if (res) return res } } }Copy the code

Continue to update ~~~