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
- Return x=promise2 reject(new TypeError(‘error’));
- It returns a promise
- The return is not a promise
- 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
- Write a normal throttle first
- Current >wait func execute previous=now
- Trailing also fires the last time (default)
- Later setTimeout Clears the timer
- Add leading==false to delay the first click
- Make the first go seTimeout logic previous = now
- 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
- Implementing a LazyMan can be called as follows: LazyMan(” Hank “) output: Hi! This is Hank!
- LazyMan (” Hank “). Sleep (10) eat (” dinner “) output Hi! This is Hank! // Wait 10 seconds.. Wake up after 10 Eat dinner
- LazyMan(” Hank “).eat(” dinner “).eat(” supper “) output Hi This is Hank! Eat dinner ~ Eat supper
- 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