Event subscription publishing

class EventEmitter {
    constructor() {
        this._events = {}
    }
    on(evtName, handler) {
        if (!this._events) this._events = {}
        if (this._events[evtName]) {
            this._events[evtName].push(handler)
        } else {
            this._events[evtName] = [handler]
        }
    }

    emit(evtName, data) {
        if (!this._events) this._events = {}
        if (this._events[evtName]) {
            this._events[evtName].forEach(fn= > fn(data))
        }
    }

    off(evtName, handler) {
        if (!this._events) this._events = {}
        if (this._events[evtName]) {
            this._events[evtName] = this._events[evtName].filter(fn= >fn ! == handler &&fn.l! ==handler) } }// Only trigger once, then uninstall
    once(evtName, handler) {
        const once=(data) = >{
           handler(data)
           this.off(evtName,once)
        }
        once.l=handler
        this.on(evtName,once)

    }
}
// Set the maximum listening value
class EventEmitter {
    constructor() {
        this._events = {}
        this.maxListeners=maxListeners||Infinity
    }
    on(evtName, handler) {
        if (!this._events) this._events = {}
        if(this.maxListener! + =Infinity&&this.events[event].length>=this.maxListeners){
        console.warn('Current event${event}Exceeds the maximum number of listeners)}if (this._events[evtName]) {
            this._events[evtName].push(handler)
        } else {
            this._events[evtName] = [handler]
        }
    }

    emit(evtName, data) {
        if (!this._events) this._events = {}
        if (this._events[evtName]) {
            this._events[evtName].forEach(fn= > fn(data))
        }
    }

    off(evtName, handler) {
        if (!this._events) this._events = {}
        if (this._events[evtName]) {
            this._events[evtName] = this._events[evtName].filter(fn= >fn ! == handler &&fn.l! ==handler) } }// Only trigger once, then uninstall
    once(evtName, handler) {
        const once=(data) = >{
           handler(data)
           this.off(evtName,once)
        }
        once.l=handler
        this.on(evtName,once)

    }
}
Copy the code

The function is currified

Record the number of arguments passed in each call and compare it with the number of arguments of the function. If the number of arguments is not met, the new function is returned. If the number of arguments passed is consistent with the number of arguments, the original function is executed.

function curring(fn){
 const inner=(. args) = >{
 	returnargs.length>=fn.length? fn(... args):(. userArgs) = >inner(... args,... userArgs); }returninner(); } implement the continuous add functionfunction Add() {
    const nums = [...arguments];
    function AddPro() { nums.push(... arguments);return AddPro;
    }
    AddPro.sumOf = () = > {
        return nums.reduce((a, b) = > a + b);
    }
    return AddPro;
}
Copy the code

compose

function compose(. fn){
	if(! fn.length)return v= >v;
	if(fn.length===1)return fn[0];
	return fn.reduce((acc,cur) = >(. args) = >acc(cur(... args))) }Copy the code

Promise

The beggar version


const PENDING="PENDING";
const FULFILLED="FULFILLED";
const REJECTED="REJECTED";

class Promise{
 constructor(executor){
 	this.status=PENDING;
 	this.value=undefined;
 	this.reason=undefined;
 	this.onResolvedCallbacks=[];
 	this.onRejectedCallbacks=[];
 	const resolve=(value) = >{
 		if(this.status===PENDING){
 			this.value=value;
 			this.status=FULFILLED;
 			this.onResolvedCallbacks.forEach(fn= >fn())
 		}

 	}
 	const reject=(reason) = >{
 		if(this.status===PENDING){
 			this.reason=reason;
 			this.status=REJECTED;
 			this.onRejectedCallbacks.forEach(fn= >fn())
 		}
 	}
 	try{
      executor(resolve,reject)
 	}catch(e){
      reject(e)
 	}
 }
 then(onFulfilled,onRejected){
   if(this.status===PENDING){
   	this.onResolvedCallbacks.push(

   	() = >{
   		onFulfilled(this.value)
   	})
   this.onRejectedCallbacks.push(

   	() = >{
   			onRejected(this.reason)
   	})
   }
   if(this.status===FULFILLED){
   	onFulfilled(this.value)
   }
   if(this.status===REJECTED){
   	onRejected(this.reason)
   }
 }
}
Copy the code

PromiseA + version

Implementation approach

  • Ordinary promise
  • The Promise executor passes the asynchronous code Callbacks queue to hold the event
  • Promise. Then execution can also be abnormal so try catch is always included
  • Then chain calls return promise2 to get primose2 plus setTimeout
  • Resolve (x) x may be a promise
  • resolvePromise
  1. Return x=promise2 reject(new TypeError(‘error’));
  2. It returns a promise
  3. The return is not a promise
  4. Called compatible with a promise written by someone else that the state changes only once
const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';


// Use x to determine whether to call promise2 resolve or reject
function resolvePromise(promise2, x, resolve, reject) {
    // Core process
    if (promise2 === x) {
        return reject(new TypeError('wrong'))}// Any promises I may write should be compatible with other people's promises, considering cases where I didn't write my own promises
    if ((typeof x === 'object'&& x ! = =null) | |typeof x === 'function') { // It can be a promise
        // Other people's promises can be called successfully and then fail ~~~ to ensure that other people's promises comply with the specification
        let called = false;
        try { // It is possible that an exception may occur when the then method implements the value via defineProperty
            let then = x.then;
            if (typeof then === 'function') {
                X.teng will trigger the getter and an exception may occur
                then.call(x, y= > {
                    if (called) return;
                    called = true;
                    resolvePromise(promise2, y, resolve, reject); // Until the resolution is not a promise location
                }, r= > { // reason
                    if (called) return;
                    called = true;
                    reject(r);
                });
            } else { // {} {then:{}}
                resolve(x); / / constant}}catch (e) {
            if (called) return;
            called = true; reject(e); }}else {
        resolve(x); // this returns a normal value and pushes it directly into promise2. Resolve}}class Promise {
    constructor(executor) {
        this.status = PENDING; // Promise default state
        this.value = undefined; // The reason for success
        this.reason = undefined; // Cause of failure
        this.onResolvedCallbacks = []; // Store the successful callback method
        this.onRejectedCallbacks = []; // Store the failed callback method
        const resolve = (value) = > { // The resolve function succeeds
            if(value instanceof Promise) {return value.then(resolve,reject)
            }
            if (this.status === PENDING) {
                this.value = value;
                this.status = FULFILLED; // Change the status
                / / release
                this.onResolvedCallbacks.forEach(fn= >fn()); }}const reject = (reason) = > { // Failed reject function
            if (this.status === PENDING) {
                this.reason = reason;
                this.status = REJECTED // Change the status
                this.onRejectedCallbacks.forEach(fn= >fn()); }}try {
            executor(resolve, reject);
        } catch(e) { reject(e); }}The arguments in then are optional
    then(onFulfilled, onRejected) { // onFulfilled, onRejected
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v= > v;
        onRejected = typeof onRejected === 'function' ? onRejected : err= > { throw err; }
        // Used to implement chain calls
        let promise2 = new Promise((resolve, reject) = > {
            // Subscription mode
            if (this.status == FULFILLED) { // Successfully called the successful method
                setTimeout(() = > {
                    try {
                        let x = onFulfilled(this.value);
                        // If x is a promise, it is a promise that succeeds or fails. Then, if it succeeds, it passes the result of a call to promise2's resolve and if it fails

                        // The value of x determines whether to call promise2 resolve or reject (promise), or resolve (normal)
                        resolvePromise(promise2, x, resolve, reject);
                    } catch(e) { reject(e); }},0);
            }
            if (this.status === REJECTED) { // fail to call the failed method
                setTimeout(() = > {
                    try {
                        let x = onRejected(this.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch(e) { reject(e); }},0);

            }
            if (this.status == PENDING) { // Code calls resolve or reject asynchronously
                this.onResolvedCallbacks.push(() = > { // slice programming AOP
                    setTimeout(() = > {
                        try {
                            // todo...
                            let x = onFulfilled(this.value);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch(e) { reject(e); }},0);

                });
                this.onRejectedCallbacks.push(() = > {
                    setTimeout(() = > {
                        try {
                            // todo...
                            let x = onRejected(this.reason);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch(e) { reject(e); }},0); }); }})return promise2
    }
    static resolve(value){
        return new Promise((resolve,reject) = >{ resolve(value); })}static reject(value){
        return new Promise((resolve,reject) = >{ reject(value); })}catch(errorFn){
        return this.then(null,errorFn)
    }
}
// npm install promises-aplus-tests -g


// Delay objects help us reduce the number of applications: they are not widely used at the moment
Promise.deferred = function () {
    let dfd = {};
    dfd.promise = new Promise((resolve,reject) = >{
        dfd.resolve= resolve;
        dfd.reject = reject;
    }); 
    return dfd;
}
Copy the code

Promise.all

Promise.all = function(promises) {
    return new Promise((resolve, reject) = > {
        if (!Array.isArray(promises)) return reject(new Error("The parameter passed in must be an array."))
        let result = [];
        let times = 0;
        const processSuccess = (index,val) = >{
            result[index] = val;
            if(++times === promises.length){
                resolve(result)
            }
        }
        for (let i = 0; i < promises.length; i++) { // Multiple requests are executed concurrently
            let p = promises[i]
            if(p && typeof p.then === 'function'){
                p.then((data) = >{
                    processSuccess(i,data)
                },reject); // If one of these promises fails, it simply fails to implement
            }else{
                processSuccess(i,p)
            }
        }
    });
}
function myPromiseAll(promises) {
    return new Promise((resolve, reject) = > {
        if (!Array.isArray(promises)) return reject(new Error("The parameter passed in must be an array."))
        let res = [],
            count = 0,
            len = promises.length;
        for (let i = 0; i < len; i++) {
            Promise.resolve(promises[i]).then(val= > {
                count++;
                res[i] = val;
                if (count === len) {
                    resolve(res)
                }
            }).catch(e= > reject(e))
        }
    })
}

function myPromiseAll(promises) {
    return new Promise((resolve, reject) = > {
        if (!Array.isArray(promises)) return reject(new Error("The parameter passed in must be an array."))
        let res = [],
            count = 0,
            len = promises.length;
        const processSuccess = (index, val) = > {
            res[index] = val
            if (++count == len) {
                resolve(res)
            }
        }
        for (let i = 0; i < len; i++) {
            let p = promises[i]
            Promise.resolve(p).then(val= > processSuccess(i, val), reject)
        }

    })
}
Copy the code

Promise.race

Promise.race=function(promises){
	return new Promise((resolve,reject) = >{
		for(let i=0; i<promises.length; i++){let p=promises[i]
			if(p && typeof p.then === 'function'){
			p.then(resolve,reject)

		}else{
			resolve(p)
		}
		}
	})
}
Copy the code

Promise that can abort

function warp(p1){
	let p=new Promise((resolve,reject) = >{abort=reject})
	let p2=Promise.race([p,p1])
	p2.abort=abort;
	reject p2;
}
Copy the code

Promise.finally

Promise.finally=function(cb){
	return this.then((data) = >{
			return Promise.resolve(cb()).then(() = >data)
		},() = >{
			return Promise.resolve(cb()).then(() = >throw err)
		}		)
}
Copy the code

promiseify

function promiseify(fn) {
	return function(. args) {
		return new Promise((resolve, reject) = >{ fn(... args,(err, data) = > {
				if (err) return reject(err)
				resolve(data)
			}
		})
	}
}

function promiseifyAll(obj){
	let o={};
	for(key in obj){
		if(typeof obj[key]==='function'){
			o[key+'Promise']=promiseify(o[key])
		}
	}
	return o;
}
Copy the code

Promise implements concurrency limits

function limitLoad(urls, handler, limit) {
    const sequence = [].concat(urls);
    let promises = [];
    promises = sequence.splice(0, limit).map((url, index) = > {
        return handler(url).then(() = > {
            return index
        })
    });
    let p = Promise.race(promises);
    for (let i = 0; i < sequence.length; i++) {
        p = p.then((res) = > {
            promises[res] = handler(sequence[i]).then(() = > {
                return res;
            })
            return Promise.race(promises)
        })
    }
}
Copy the code

Promise implementation serial

function executePromises(createPromises) {
  var result = Promise.resolve();
  createPromises.forEach(function (createPromise) {
    result = result.then(createPromise);
  });
  return result;
}
function createPromise() {
  return new Promise((resolve) = >{
      doSomthing()
      resolve()
  });
}

const promiseChain=promiseList.reduce((acc,cur) = >{
   return acc.then(cur)
},Promise.resolve())
Copy the code

sleep

function sleep(time){
   	return new Promise((resolve,reject) = >{
   		settimeout(() = >{resolve()},time)
   	})
   }
Copy the code

Output queues in order

class Queue{
   constructor(){
       this.queue = [];
   }

   task(delay, callback){
       this.queue.push({
           delay,
           callback
       });
       return this;
   }

   async start(){
       for(let i=0; i<this.queue.length; i++){await new Promise((resolve) = >{
               setTimeout(resolve, this.queue[i].delay)
           }).then(() = >{
               this.queue[i].callback(); })}}}Copy the code

Anti-shake and throttling

debounce

function debounce(func, wait, immediate) {
	let timeout, result;
	let debounced = function() {
		if (timeout) {
			clearTimeout(timeout);
		}
		if (immediate) {
			letcallNow = ! timeout; +if (callNow) result = func.apply(this.arguments);

		}

		timeout = setTimeout(() = > {
			func.apply(this.arguments);
+			timeout = null;
		}, wait);
		return result;
	}
	debounced.cancel = function() {
		clearTimeout(timeout);
		timeout = null;
	};
	return debounced;
}
Copy the code

throttle

  1. Write a normal throttle first
  2. Current >wait func execute previous=now
  3. Trailing also fires the last time (default)
  4. Later setTimeout Clears the timer
  5. Add leading==false to delay the first click
  6. Make the first go seTimeout logic previous = now
  7. Later ==false 0
function(func, wait, options) {
	let timeout, context, args, result;
	let previous = 0;
	if(! options) options = {};let later = function() {
+		previous = options.leading === false ? 0 : Date.now();
		result = func.apply(context, args);
                if(! timeout) context = args =null;
	};

	let throttled = function() {
		context = this;
		args = arguments;
		let now = Date.now();
+		if(! previous && options.leading ===false) previous = now;
		let remaining = wait - (now - previous);
		if (remaining <= 0) {
			if (timeout) {
				clearTimeout(timeout);
				timeout = null; } previous = now; result = func.apply(context, args); +}else if(! timeout && options.trailing ! = =false) {
			timeout = setTimeout(later, remaining);
		}
		return result;
	};

	throttled.cancel = function() {
		clearTimeout(timeout);
		 timeout = context = args = null;
	};

	return throttled;
};
Copy the code

co

function co(it) {
	return new Promise((resolve, reject) = > {
		function next(data) {
			let {
				value,
				done
			} = it.next(data);
			if (done) {
				resolve(value)
			} else {
				Promise.resolve(value).then(next, reject) } } next(); })}Copy the code

The list


class Node {
	constructor(element, next) {
		this.element = element;
		this.next = next; }}class LinkedList {
	constructor() {
		this.head = null;
		this.size = 0;
	}

	_node(index) {
		if (index < 0 || index > this.size) throw new Error('cross');
		let current = this.head;
		for (let i = 0; i < index; i++) {
			 current = current.next
		}
		return current
	}
	add(index, element) {
		if (arguments.length === 1) {
			element = index
			index = this.size
		}
		if (index < 0 || index > this.size) throw new Error('cross');
		if (index === 0) {
			let head = this.head;
			this.head = new Node(element, head)
		} else {
			let prevNode = this._node(index - 1);
			prevNode.next = new Node(element, prevNode.next)
		}
		this.size++;
	}
	remove(index) {
		if (index < 0 || index > this.size) throw new Error('cross');
		if (index === 0) {
			this.head = this.head.next;
		}else{
			let prevNode=this._node(index-1)
			prevNode.next=prevNode.next.next
		}
		this.size--; }}Copy the code

Reverse a linked list

// Solution 1: recursion
function reverse(head) {
	if (head == null || head.next == null) return head;
	let newHead = reverse(head.next);
	head.next.next = head;
	head.next = null;
	return newHead;
	}
// Create a new list
function reverse(head) {
	if (head == null || head.next == null) return head;
	let newHead = null;while(head ! = =null) {
		let temp = head.next;
		head.next = newHead;
		newHead = head;
		head = temp;
	}
	return newHead;
}
Copy the code

The tree


class Node {
    constructor(element, parent) {
        this.element = element;
        this.parent = parent;
        this.left = null;
        this.right = null; }}class Tree {
    constructor() {
        this.root = null;
    }
    add(element) {
        if (this.root === null) {
           return  this.root = new Node(element);
        }
        // We can use recursion, we can use loop
        let currentNode = this.root; // Update the current node
        let parent;
        let compare;
        while (currentNode) {
            compare = currentNode.element < element;
            parent = currentNode; // Record nodes before traversal
            if (compare) { // Update the node for comparison
                // Take the right node as the root node
                currentNode = currentNode.right
            } else {
                currentNode = currentNode.left // When 8 is inserted, there is no one on the right}}// compare; // Left or right
        // parent; // To whom
        let node = new Node(element, parent)
        if (compare) {
            parent.right = node
        } else {
            parent.left = node
        }
      
    }
}
Copy the code

The former sequence traversal

preorderTraversal() {
	const traversal = (node) = > {
	if (node === null) return
        console.log(node.element); // Access the root node first
        traversal(node.left); // Access the left subtree
        traversal(node.right);// Access the right subtree
    }
    traversal(this.root);
} 
Copy the code

In the sequence traversal

inorderTraversal() {
    const traversal = (node) = > {
        if (node === null) return
        traversal(node.left);
        console.log(node.element);
        traversal(node.right);
    }
    traversal(this.root);
}
Copy the code

After the sequence traversal

postorderTraversal() {
    const traversal = (node) = > {
    if (node === null) return
        traversal(node.left);
        traversal(node.right);
        console.log(node.element);
    }
    traversal(this.root);
}
Copy the code

Sequence traversal

levelOrderTraversal() {
    if (this.root == null) return;
    let stack = [this.root];
    let currentNode = null;
    let index = 0;
    while (currentNode = stack[index++]) {
        console.log(currentNode.element); 
        if (currentNode.left) {
            stack.push(currentNode.left);
        }
        if(currentNode.right) { stack.push(currentNode.right); }}}Copy the code

Invert the binary tree

invertTree(){
    if (this.root == null) return;
    let stack = [this.root];
    let currentNode = null;
    let index = 0;
    while (currentNode = stack[index++]) {
        let tmp = currentNode.left;
        currentNode.left = currentNode.right;
        currentNode.right = tmp
        if (currentNode.left) {
            stack.push(currentNode.left);
        }
        if(currentNode.right) { stack.push(currentNode.right); }}return this.root;
}
Copy the code

List to the tree

[{id: 1.text: Nodes' 1 '.parentId: 0 // The top-level node is represented by 0
    },
    {
        id: 2.text: '1 _1 nodes'.parentId: 1 // Use this field to determine the child and parent levels
    }
    ...
]

转成
[
    {
        id: 1.text: Nodes' 1 '.parentId: 0.children: [{id:2.text: '1 _1 nodes'.parentId:1}}]]Copy the code
function listToTree(data) {
  let temp = {};
  let treeData = [];
  for (let i = 0; i < data.length; i++) {
    temp[data[i].id] = data[i];
  }
  for (let i in temp) {
    if(+temp[i].parentId ! =0) {
      if(! temp[temp[i].parentId].children) { temp[temp[i].parentId].children = []; } temp[temp[i].parentId].children.push(temp[i]); }else{ treeData.push(temp[i]); }}return treeData;
}

Copy the code

Deep copy

function copy(obj, hash = new WeakMap(a)) {
    if (obj instanceof Date) return new Date(obj);
    if (obj instanceof RegExp) return new RegExp(obj);
    if (typeofobj ! = ="object" || obj === null) return obj;
    if (hash.get(obj)) return hash.get(obj);
    let res = obj instanceof Array ? [] : {};
    hash.set(obj, res);
    for (const [k, v] of Object.entries(obj)) {
        res[k] = copy(v, hash);
    }
    return res;
}
 
 function clone(target, map = new Map(a)) {
    if (typeof target === 'object') {
        let cloneTarget = Array.isArray(target) ? [] : {};
        if (map.get(target)) {
            return target;
        }
        map.set(target, cloneTarget);
        for (const key in target) {
            cloneTarget[key] = clone(target[key], map);
        }
        return cloneTarget;
    } else {
        returntarget; }};Copy the code

The depth of the comparison

function isEqual(obj1, obj2) {
    if(! isObject(obj1) || ! isObject(obj2)) {// Value type (note that participants in equal are generally not functions)
        return obj1 === obj2
    }
    if (obj1 === obj2) {
        return true
    }
    // Both are objects or arrays and are not equal
    // 1. First fetch obj1 and obj2 keys and compare the number
    const obj1Keys = Object.keys(obj1)
    const obj2Keys = Object.keys(obj2)
    if(obj1Keys.length ! == obj2Keys.length) {return false
    }
    // 2. Compare with obj2 recursively against obj1
    for (let key in obj1) {
        // Compare the val of the current key -- recursive!!
        const res = isEqual(obj1[key], obj2[key])
        if(! res) {return false}}// 3
    return true
}

Copy the code

Lazyman

  1. Implementing a LazyMan can be called as follows: LazyMan(” Hank “) output: Hi! This is Hank!
  2. LazyMan (” Hank “). Sleep (10) eat (” dinner “) output Hi! This is Hank! // Wait 10 seconds.. Wake up after 10 Eat dinner
  3. LazyMan(” Hank “).eat(” dinner “).eat(” supper “) output Hi This is Hank! Eat dinner ~ Eat supper
  4. LazyMan(” Hank “).sleepfirst (5).eat(” supper “) output Eat supper
    class Lazy {
        constructor(name) {
            this.sleepFirstTime = 0;
            this.promise = Promise.resolve().then(
                () = > this.sleepFirstTime && this._sleep(this.sleepFirstTime)
            ).then(() = > {
                console.log(`Hi! This is ${name}! `);
            });
        }
        sleepFirst(time) {
            this.sleepFirstTime = time;
            return this;
        }
        eat(food) {
            this.promise = this.promise.then(() = > {
                console.log(`Eat ${food}~ `);
            });
            return this;
        }
        sleep(time) {
            this.promise = this.promise.then(() = > this._sleep(time));
            return this;
        }
        _sleep(time) {
            return new Promise((next) = > {
                setTimeout(() = > {
                    console.log(`Wake up after ${time}`); next(); }, time); }); }}function LazyMan(name) {
        return new Lazy(name);
    }
Copy the code

call/bind/apply

!function (proto) {
    function getContext(context) {
        context = context || window;
        let type = typeof context;
        if (['number'.'string'.'boolean'.'null'].includes(type)) {
            context=Object(context)
        }
        return context;
    }
    function call(context, ... args) {
        context = getContext(context);
        let symbol=Symbol('fn')
        context[symbol] = this;
        letresult = context[symbol](... args);delete context[symbol];
        return result;
    }
    function apply(context, args) {
        context = getContext(context);
        let symbol=Symbol('fn')
        context[symbol] = this;
        letresult = context[symbol](... args);delete context[symbol];
        return result;
    }

    function bind(context, ... bindArgs) {
        return (. args) = > this.call(context, ... bindArgs, ... args); } proto.call = call; proto.apply = apply; proto.bind = bind; } (Function.prototype)
Copy the code

Object.create

Object.create = function(obj) {
	function Fn() {};
	Fn.prototype = obj;
	return new Fn();
}
Copy the code

new

function New(fn, ... args) {
	let instance = Object.create(fn.prototype);
	letresult = fn.call(instance, ... args);return typeof result === "object" ? result : instance;
}
Copy the code

instanceof

function myInstanceof(left, right) {
    let proto = Object.getPrototypeOf(left);
    while(true) {
        if(proto == null) return false;
        if(proto == right.prototype) return true;
        proto = Object.getPrototypeof(proto); }}Copy the code

Binary search

function bsearch(A, x) {
	let l = 0,
		r = A.length - 1,
		guess;
	while (l <= r) {
		guess = Math.floor((l + r) / 2)
		if (A[guess] === x) return guess
		else if (A[guess] > x) r = guess - 1
		else l = guess + 1
	}
	return -1
}
Copy the code

Array to heavy

//1. The double-layer for loop NaN is not removed
function uniq(arr) {
    for (let i = 0; i < arr.length; i++) {
        for (let j = i + 1; j < arr.length; j++) {
            if (arr[i] === arr[j]) {
                arr.splice(j, 1); j--; }}}return arr;
}
//2. NaN is not removed after sorting
function uniq(arr) {
    arr.sort();
    for (let i = 0; i < arr.length - 1; i++) {
        arr[i] === arr[i + 1] && arr.splice(i + 1.1) && i--;
    }
    return arr;
} 
//3. Indexof NaN is removed
function uniq(arr) {
    let res = [];
    for (let i = 0; i < arr.length; i++) {
        if(arr.indexOf(arr[i]) === i) { res.push(arr[i]); }}return res;
}
function uniq2(arr) {
    return arr.filter((item, index) = > {
        return arr.indexOf(item) === index
    })
}
//4.reduce
function uniq6(arr){
	return arr.reduce((acc,cur) = >{
		if(! acc.includes(cur)){ acc.push(cur) }return acc
	},[])
}
let  uniq2 = arr.sort().reduce((acc, current) = > {
    if(acc.length === 0 || acc[acc.length-1] !== cur) {
        acc.push(cur);
    }
    returnacc; } []);//5.includes includes
function uniq(arr) {
    let res = [];
    for (let i = 0; i < arr.length; i++) {
        if (!res.includes(arr[i])) {
            res.push(arr[i]);
        }
    }
    return res;
}
//6.Map can delete NaN
function uniq(arr) {
    let map = new Map(a);for (let i = 0; i < arr.length; i++) { ! map.has(arr[i]) && map.set(arr[i],true);
    }
    return [...map.keys()];
}
//7. Set can replicate NaN
function uniq(arr) {
    return [...new Set(arr)];
}

Copy the code

Array flattening

// 1.reduce
function flatten(arr) {
      return arr.reduce((result, item) = > {
          return result.concat(Array.isArray(item) ? flatten(item) : item); } []); };function flat(arr, num = 1) {
  return num > 0
    ? arr.reduce(
        (pre, cur) = >
          pre.concat(Array.isArray(cur) ? flat(cur, num - 1) : cur),
        []
      )
    : arr.slice();
}
// 2.map
function flatten2(arr) {
    let res = [];
    arr.map(item= > {
        if(Array.isArray(item)) {
            res = res.concat(flatten2(item));
        } else{ res.push(item); }});return res;
}
//3.while ...
function flatten(arr){
  while (arr.some(item= > Array.isArray(item))){ arr = [].concat(... arr); }return arr;
}
//4.stack
function flat(arr) {
  const result = []; 
  const stack = [].concat(arr);  // Copy the array elements onto the stack. Assignment directly changes the original array
  // If the stack is not empty, the loop is iterated
  while(stack.length ! = =0) {
    const val = stack.pop(); 
    if (Array.isArray(val)) { stack.push(... val);// If the array is pushed again and a layer is expanded
    } else {
      result.unshift(val); // If it's not an array, put it in the result array}}return result;
}
//5. Jion split is only used for numbers
let flatten1 = a.join(', ').split(', ').map(Number)
let flatten2 = JSON.stringify(a).replace(/\[|\]/g.' ').split(', ').map(Number);
Copy the code

The object is flat

function objectFlat(obj = {}) {
  const res = {}
  function flat(item, preKey = ' ') {
    Object.entries(item).forEach(([key, val]) = > {
      const newKey = preKey ? `${preKey}.${key}` : key
      if (val && typeof val === 'object') {
        flat(val, newKey)
      } else {
        res[newKey] = val
      }
    })
  }
  flat(obj)
  return res
}

Copy the code

Inverted string

var reverseString = function(s) {
    const n = s.length;
    for (let left = 0, right = n - 1; left < right; ++left, --right) { [s[left], s[right]] = [s[right], s[left]]; }};Copy the code

JSON.Stringify

function jsonStringify(obj) {
    let type = typeof obj;
    if(type ! = ="object") {
        if (/string|undefined|function/.test(type)) {
            obj = '"' + obj + '"';
        }
        return String(obj);
    } else {
        let json = []
        let arr = Array.isArray(obj)
        for (let k in obj) {
            let v = obj[k];
            let type = typeof v;
            if (/string|undefined|function/.test(type)) {
                v = '"' + v + '"';
            } else if (type === "object") {
                v = jsonStringify(v);
            }
            json.push((arr ? "" : '"' + k + '" :) + String(v));
        }
        return (arr ? "[" : "{") + String(json) + (arr ? "]" : "}")}}Copy the code

An array of random sequence

//Fisher -- Yates Shuffle algorithm
// Start at the end of the array, select the last element, and swap positions with random elements in the array
// Then create a random position in the position other than the last one, and swap that position element with the next-to-last one
function shuffle(arr) {
  let len = arr.length;
  while (len) {
    let i = (Math.random() * len--) >> 0; 
    let temp = arr[len];
    arr[len] = arr[i];
    arr[i] = temp;
  }
  return arr;
}
// Use shuffle algorithm to randomly select numbers
function getRandomArrElement(array, count) {
    let arr = array.slice(0), 
        i = arr.length, 
        min = i - count, 
        temp, 
        index;
    while (i > min) {
        index = Math.floor((i--) * Math.random());
        temp = arr[index];
        arr[index] = arr[i];
        arr[i] = temp;
    }
    return arr.slice(min);
}
// Generate random numbers in the range
function setRangeRandom(min, max) { 
        let n = max - min;
        if (n == 0) {
            return max
        } else if (n < 0) {
            [max, min] = [min, max];
            n = Math.abs(n);
        }
        return  Math.random()* n+min;
    }
Copy the code

JSON.parse

/ / method
(new Function('return ' + jsonStr))();
2 / / method
function jsonParse(opt) {
    return eval('(' + opt + ') ');
}
Copy the code

Parasitic combinatorial inheritance

function Super() {}
function Sub() {
    Super.call(this)
}
Sub.prototype = new Super();
Sub.constructor = Sub;
Copy the code

Realize the line and hump conversion

function camelize(str) {
    return (str + ' ').replace(/-\D/g.function(match) {
        return match.charAt(1).toUpperCase()
    })
}
function hyphenate(str) {
    return (str + ' ').replace(/[A-Z]/g.function(match) {
        return The '-'+ match.toLowerCase(); })}Copy the code

Implementing ajax

function ajax({url, methods, headers}) {
    return new Promise((resolve, reject) = > {
        let xhr =  XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
        xhr.open(methods,url);
        for(let key in headers) {
            let value = headers[key]
            xhr.setRequestHeader(key, headers[key]);
        }
        xhr.onreadystatechange = () = > {
            if(xhr.readyState === 4) {
                if(xhr.status === 200 || xhr.status === 304) {
                    resolve(xhr.response);
                } else {
                    reject(new Error(xhr.responseText)) } } } xhr.send(); })}Copy the code

Achieve the maximum number of concurrent requests

function asyncPool(poolLimit, array, iteratorFn) {
    let i = 0;
    const ret = [];
    const executing = [];
    const enqueue = function () {
        // array is an empty array
        if (i === array.length) {
            return Promise.resolve();
        }
        // Each time enqueue is invoked, a promise is initialized
        const item = array[i++];
        const p = Promise.resolve().then(() = > iteratorFn(item, array));
        // Enter promises array
        ret.push(p);
        // Promise is executed and deleted from the executing array
        const e = p.then(() = > executing.splice(executing.indexOf(e), 1));
        // Insert a executing number to indicate the executing promise
        executing.push(e);
        Rece: Whenever the number of promises in the executing array is lower than poolLimit, the new Promise is instantiated and executed
        let r = Promise.resolve();
        if (executing.length >= poolLimit) {
            r = Promise.race(executing);
        }
        // recurse until the array is traversed
        return r.then(() = > enqueue());
    };
    return enqueue().then(() = > Promise.all(ret));
}

Copy the code
function sendRequest(urls, num, callback) {(function request(res) {
        urls.length ? Promise.all(urls.splice(0, num).map(url= > fetch(url))).then(r= >request(res.concat(r))) : callback(res); }) ([]); }Copy the code

Vue2 responsive


class Dep {
  static stack = []
  static target = null
  deps = null
  
  constructor() {
    this.deps = new Set()}depend() {
    if (Dep.target) {
      this.deps.add(Dep.target)
    }
  }

  notify() {
    this.deps.forEach(w= > w.update())
  }

  static pushTarget(t) {
    if (this.target) {
      this.stack.push(this.target)
    }
    this.target = t
  }

  static popTarget() {
    this.target = this.stack.pop()
  }
}

// reactive
function reactive(o) {
  if (o && typeof o === 'object') {
    Object.keys(o).forEach(k= > {
      defineReactive(o, k, o[k])
    })
  }
  return o
}

function defineReactive(obj, k, val) {
  let dep = new Dep()
  Object.defineProperty(obj, k, {
    get() {
      dep.depend()
      return val
    },
    set(newVal) {
      val = newVal
      dep.notify()
    }
  })
  if (val && typeof val === 'object') {
    reactive(val)
  }
}

// watcher
class Watcher {
  constructor(effect) {
    this.effect = effect
    this.update()
  }

  update() {
    Dep.pushTarget(this)
    this.value = this.effect()
    Dep.popTarget()
    return this.value
  }
}

Copy the code

Vue3 responsive

/** * Vue3 responsivity principle ** /

// Determine if it is an object
function isObject(val) {
  return typeof val === "object"&& val ! = =null;
}
function hasOwn(target, key) {
  return target.hasOwnProperty(key);
}
// WeakMap: Weakreference mapping table
// Original object: proxied object
let toProxy = new WeakMap(a);// Proxied object: original object
let toRaw = new WeakMap(a);// Reactive core methods
function reactive(target) {
  // Create a responsive object
  return createReactiveObject(target);
}
function createReactiveObject(target) {
  // If the object is not currently an object, just return it
  if(! isObject(target)) {return target;
  }
  // If already proxied, the proxied result is returned directly
  let proxy = toProxy.get(target);
  if (proxy) {
    return proxy;
  }
  // Prevent proxied objects from being proxied again
  if (toRaw.has(target)) {
    return target;
  }
  let baseHandler = {
    get(target, key, receiver) {
      // Reflect is a built-in object that provides methods to intercept JavaScript operations. These methods are the same as the proxy Handlers method.
      let res = Reflect.get(target, key, receiver);
      // Collect dependencies/subscriptions to map current keys to effects
      track(target, key);
      // If the value of get is an object, then it is recursive (this is an optimization compared to the default recursion in Vue2).
      return isObject(res) ? reactive(res) : res;
    },
    set(target, key, value, receiver) {
      // We need to distinguish between new attributes and modified attributes
      let hasKey = hasOwn(target, key);
      let oldVal = target[key];
      let res = Reflect.set(target, key, value, receiver);
      if(! hasKey) {console.log("New Properties");
        trigger(target, "add", key);
      } else if(oldVal ! == value) {console.log("Modify properties");
        trigger(target, "set", key);
      }
      return res;
    },
    deleteProperty(target, key) {
      let res = Reflect.deleteProperty(target, key);
      returnres; }};let observed = new Proxy(target, baseHandler);
  toProxy.set(target, observed);
  toRaw.set(observed, target);
  return observed;
}

{name:[effect]}
let activeEffectStacks = [];
let targetsMap = new WeakMap(a);// If the target key changes, the array method is executed
function track(target, key) {
  // Get the top of the stack function
  let effect = activeEffectStacks[activeEffectStacks.length - 1];
  if (effect) {
    // Get the dependency table for target
    let depsMap = targetsMap.get(target);
    if(! depsMap) { targetsMap.set(target, (depsMap =new Map()));
    }
    // Get the set of response functions corresponding to key
    let deps = depsMap.get(key);
    // Dynamically create dependencies
    if(! deps) { depsMap.set(key, (deps =new Set()));
    }
    if(! deps.has(effect)) { deps.add(effect); }}}function trigger(target, type, key) {
  let depsMap = targetsMap.get(target);
  if (depsMap) {
    let deps = depsMap.get(key);
    if (deps) {
      // Execute the effects corresponding to the current key
      deps.forEach((effect) = >{ effect(); }); }}}// Reactive side effects
function effect(fn) {
  const rxEffect = function () {
    try {
      // Catch an exception
      // Run fn and save effect
      activeEffectStacks.push(rxEffect);
      return fn();
    } finally{ activeEffectStacks.pop(); }};// It should be executed once by default
  rxEffect();
  // Return the response function
  return rxEffect;
}
Copy the code

SetTimeout implementation setInterval

function timerFun(){
//todo...
let timer=setTimeout(() = >{
     timerFun();
     clearTimeout(timer)
  },1000);
}
Copy the code

RequestAnimationFrame implementation setInterval

/ / setInterval implementation
function setInterval(callback, interval) {
    let timer
    const now = Date.now
    let startTime = now()
    let endTime = startTime
    const loop = () = > {
        timer = window.requestAnimationFrame(loop)
        endTime = now()
        if (endTime - startTime >= interval) {
            startTime = endTime = now()
            callback(timer)
        }
    }
    timer = window.requestAnimationFrame(loop)
    return timer
}

let a = 0
setInterval(timer= > {
    console.log(a)
    a++
    if (a === 3) window.cancelAnimationFrame(timer)
}, 1000)
/ / 0
/ / 1
/ / 2

Copy the code

RequestAnimationFrame implementation setTimeout

/ / setTimeout implementation
function setTimeout(callback, interval) {
    let timer
    const now = Date.now
    let startTime = now()
    let endTime = startTime
    const loop = () = > {
        timer = window.requestAnimationFrame(loop)
        endTime = now()
        if (endTime - startTime >= interval) {
            callback(timer)
            window.cancelAnimationFrame(timer)
        }
    }
    timer = window.requestAnimationFrame(loop)
    return timer
}

let a = 0
setTimeout(timer= > {
    console.log(a)
    a++
}, 1000)
/ / 0

Copy the code

Addition of large Numbers

function add(a ,b){
   let maxLength = Math.max(a.length, b.length);
   // use 0 to complete the length
   a = a.padStart(maxLength , 0);/ / "0009007199254740991"
   b = b.padStart(maxLength , 0);/ / "1234567899999999999"
   // Define the variables to be used in the addition process
   let t = 0;
   let f = 0;   / / "carry"
   let sum = "";
   for(let i=maxLength-1 ; i>=0 ; i--){
      t = parseInt(a[i]) + parseInt(b[i]) + f;
      f = Math.floor(t/10);
      sum = t%10 + sum;
   }
   if(f==1){
      sum = "1"+ sum;
   }
   return sum;
}
Copy the code

LRU


var LRUCache = function(capacity) {
    this.capacity = capacity;
    this.map = new Map(a); }; LRUCache.prototype.get =function(key) {
    if(this.map.has(key)){
        let temp=this.map.get(key)
         this.map.delete(key);
         this.map.set(key, temp);
         return temp
    }else{
        return -1}}; LRUCache.prototype.put =function(key, value) {
    if(this.map.has(key)){
        this.map.delete(key);
    }
    this.map.set(key,value);
    if(this.map.size > this.capacity){
        this.map.delete(this.map.keys().next().value); }};Copy the code

The version number

/ / sorting
arr.sort((a, b) = > {
  let i = 0;
  const arr1 = a.split(".");
  const arr2 = b.split(".");

  while (true) {
    const s1 = arr1[i];
    const s2 = arr2[i];
    i++;
    if (s1 === undefined || s2 === undefined) {
      return arr2.length - arr1.length;
    }

    if (s1 === s2) continue;

    returns2 - s1; }});/ / than size
var compareVersion = function(version1, version2) {
 let arr1=version1.split("."),arr2=version2.split('. ');
 let maxLen=Math.max(arr1.length,arr2.length);
for(let i=0; i<maxLen; i++){ arr1[i]=arr1[i]===undefined?0:parseInt(arr1[i]);
    arr2[i]=arr2[i]===undefined?0:parseInt(arr2[i]);
    if(arr1[i]>arr2[i]){return 1}else if(arr1[i]<arr2[i])return -1;
}
return 0;
};

Copy the code

trim

String.prototype.trim = function() {
    return this.replace(/^\s+|\s+$/g.' ')}Copy the code

Use CSS to draw geometric shapes

/ / triangle.triangle {
            width: 0;
            height: 0;
            border-width: 50px;
            border-style: solid;
            border-color: #8D0EEEtransparent transparent transparent; } / / diamond.diamond {
            width: 100px;
            height: 100px;
            transform: rotate(45deg);
            background: #0CCEf2; } / / fan.sector{
          border-radius:80px 0 0;
          width: 80px;
          height: 80px;
          background: # 666;
}

Copy the code

CSS Curve Drawing

.ball{
  height: 100px;
  width: 100px;
  border-radius: 50%;
  position: absolute;
  bottom: 40px;
  left: 40px;
  background: greenyellow; } // Define the flow of animation.run_top_right {
  display: block;
  animation: run-right-right 3s 0.4 s 1 linear, run-right-top 3s 0.4 s 1 cubic-bezier(.66.1.1.41);
  animation-fill-mode: forwards; } // Start and end values for the animation that goes up@keyframes run-right-top {
  0% {
    bottom: 40px;
  }

  100% {
    bottom: 800px; }} // Start and end values of the up-right animation@keyframes run-right-right {
  0% {
    left: 40px;
    transform: scale(0.7);
  }

  100% {
    left: 600px;
    transform: scale(0.45); }}Copy the code

Left and right fixed middle adaptive layout

// Pros and cons // Assumptions are highly unknownfloatThe absolute grid cannot be used // compatibility // float out of document flow compatibility is good.left{
	float: left;
	width: 300px;
}
.right{
	float: right;
	width: 300px;
}
.center{} // Absolutely locate out of the document flow.left{
	left: 0;
	width: 300px
	position: absolute;
}
.right{
	right: 0;
	width: 300px;
	position: absolute;
}
.center{
	left: 300px;
	right: 300px;
	position: absolute; } / /flexIe8 does not support parent containers {display: flex;
}
.right..left{
	width: 300px;
}
.center{
	flex: 1; } // Tablecell is compatible with both sides of the parent container at the same time {display: table;
	width: 100%
}
.left{
    display: table-cell;
	width: 300px
}
.right{
    display: table-cell;
	width: 300px;
}
.center{
    display: table-cell; } // Grid layout code concise parent container {display: grid;
	width: 100%;
	grid-template-rows: 100px;
	grid-template-columns: 300px auto 300px;
}

Copy the code

Horizontal and vertical center

.parent {
    display: table-cell;
    vertical-align: middle;

}

.son {
    margin: 0 auto;
}

.parent2 {
    position: relative;
}

.son2 {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
}

.parent3 {
    position: relative;
}

.son3 {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
}

.parent4 {
    display: flex;
    justify-content: center;
    align-items: center;
}

.son4 {}

.parent5 {
    display: flex;
    justify-content: center;
}

.son5 {
    align-self: center;
}

.parent6 {
    display: grid;
}

.son6 {
    align-self: center;
    justify-self: center;
}
.parent7 {
    display: grid;
}

.son7{
margin:auto;
}
Copy the code