The original link
Check this
The call, the apply
Function.prototype._call = function(ctx = window, ... args) {
const fnKey = 'tmp_' + Date.now();
ctx[fnKey] = this;
constresult = ctx[fnKey](... args);delete ctx[fnKey];
return result;
};
// The second argument is array
Function.prototype._apply = function(ctx = window, args = []) {
const fnKey = 'tmp_' + Date.now();
ctx[fnKey] = this;
constresult = ctx[fnKey](... args);delete ctx[fnKey];
return result;
};
let obj = { x: 1 };
function fn() {
console.log(this.x, arguments);
}
fn._call(obj, 1.2.3);
fn._apply(obj, [1.2.3]);
Copy the code
bind
Function.prototype._bind = function() {
const slice = [].slice;
const _fn = this;
const ctx = arguments[0];
const args = slice.call(arguments.1);
if (typeof_fn ! = ='function') {
throw new TypeError('Function.prototype.bind - ' +
'what is trying to be bound is not callable');
}
return function() {
const funcArgs = args.concat(slice.call(arguments));
return _fn.apply(ctx, funcArgs);
};
};
const obj = { x: 1 };
function A() {
console.log(this.x);
}
const fn = A._bind(obj);
fn();
Copy the code
new
function newObject(fn) {
const obj = {};
const res = fn.apply(obj, [].slice.call(arguments, 1));
+ Object.setPrototypeOf(obj, fn.prototype);
return res instanceof Object ? res : obj;
}
function Con(a) {
this.a = a;
}
const obj = newObject(Con, 1);
Copy the code
Chain calls
Number.prototype.add = function(num) {
num = +num;
if(num ! == num)return Number(this);
return Number(this + num);
};
let n = 1;
n.add(1).add(2).add(3);
Copy the code
Examine the prototype chain
instanceof
function instance_of(lhs, rhs) {
while (lhs) {
lhs = lhs.__proto__;
if (lhs === rhs.prototype) return true;
}
return false;
}
Copy the code
Combinatorial parasitic inheritance
function Super(){}
function Sub() {
Super.call(this); // Inherit your own attributes
}
// Inherits properties and methods from the prototype chain
Sub.prototype = Object.create(Super.prototype); // Inherit the prototype chain
Sub.prototype.constructor = Sub;
Copy the code
Object.create
if(!Object.create) {
Object.create = function(proto) {
function F(){}
F.prototype = proto;
return newF; }}Copy the code
Pure object
- Redux version
function isPlainObject(obj) {
if (typeofobj ! = ='object' || obj === null) return false;
var proto = obj;
while (Object.getPrototypeOf(proto) ! = =null) {
proto = Object.getPrototypeOf(proto);
}
return Object.getPrototypeOf(obj) === proto;
}
function A() {}
isPlainObject( new A ); // false
isPlainObject( new Object ); // true
isPlainObject( {} ); // true
Copy the code
Determine type
- JQuery version 3.4.1 track
const type = 'Boolean Number String Function Array Date RegExp Object Error Symbol'
.split(' ')
.reduce((pre, name) = > {
pre[`[object ${name}] `] = name.toLowerCase();
return pre;
}, {});
function toType( obj ) {
if ( obj == null ) {
return obj + ' ';
}
return typeof obj === 'object' || typeof obj === 'function' ?
type[ Object.prototype.toString.call( obj ) ] || 'object' :
typeof obj;
}
toType(/xxx/) // regexp
Copy the code
Check the closure
Currie,
function curry(fn, ... args) {
if(args.length >= fn.length) {
return fn.apply(null, args);
}
return (. args2) = >curry(fn, ... args, ... args2); }const add = curry(function(a, b, c) {
return a + b + c;
});
add(1.2.3);
add(1) (2) (3);
add(1.2) (3);
add(1) (2.3);
Copy the code
Examine sexual awareness
Image stabilization
function debounce(fn, delay) {
let timer = null;
return function() {
// all intermediate states are cleared
timer && clearTimeout(timer);
// Just need the final state, execute
timer = setTimeout((a)= > fn.apply(this.arguments), delay);
};
}
Copy the code
The throttle
function throttle(fn, delay) { let timer, lastTime; return function() { const now = Date.now(); const space = now - lastTime; / / time interval between the if (lastTime && space < delay) {/ / the last time in response to user action / / not for the first time, haven't to time, remove the timer, timing again. timer && clearTimeout(timer); // Reset the timer timer = setTimeout(() => {- lastTime = now; // Don't forget to record the time
+ lastTime = Date.now(); // reset the timer
fn.apply(this, arguments);
- }, delay);
+ }, delay - space); // Make sure the last time is accuratereturn; } // time = now; fn.apply(this, arguments);+ timer && clearTimeout(timer); // Don't forget to clear it
};
}
Copy the code
Throttling anti – shake details
The event agent
function delegate(ele, selector, type, fn) {
function callback(e) {
e = e || window.event;
const target = e.target || e.srcElement;
let selectors = ele.querySelectorAll(selector);
selectors = [].slice.call(selectors);
if( selectors.includes(target) ) {
fn.call(target, e);
}
}
ele.addEventListener(type, callback, false);
}
delegate(document.querySelector('body'), 'button'.'click'.function () {
console.log('bingo');
});
Copy the code
Limit concurrency
function sendRequest(urls, max, callback) {
const last = performance.now();
const len = urls.length;
let limit = max; // Control concurrency
let cnt = 0; // Total number of executed tasks
let res = []; // Store execution results in order
const tasks = urls.map((url, index) = > () => fetch(url)
.then(data= > {
res[index] = data;
})
.catch(reason= > {
res[index] = reason;
})
.finally((a)= > {
if( ++cnt === len ) return callback(res);
++limit;
doTasks();
}));
doTasks();
function doTasks() {
while( limit && tasks.length ) {
--limit;
const task = tasks.shift();
task();
console.log('Execution interval:${performance.now() - last}`); }}}/ / simulate the fetch
function fetch(url) {
return new Promise(function (resolve, reject) {
let good, bad;
const time = 3000;
good = setTimeout(function () {
clearTimeout(bad);
const data = `resolve: ${url}`;
resolve(data);
console.log(data);
}, Math.random() * time);
bad = setTimeout(function () {
clearTimeout(good);
const reason = `reject: ${url}`;
reject(reason);
console.log(reason);
}, Math.random() * time);
});
}
/ / test
sendRequest([1.2.3.4.5.6.7.8.9.10].5, (res) => console.log('all done: + res));
Copy the code
Test cross-domain
JSONP
function fn({ip}) {
console.log(ip); //
}
function jsonp(cb, domain) {
const script = document.createElement('script');
script.src = `https://api.asilu.com/ip/?callback=${cb}&ip=${domain}`;
document.querySelector('head').appendChild(script);
}
// Get baidu IP
jsonp('fn'.'www.baidu.com');
Copy the code
Check ES6
Array to heavy
- The Map version
function deleteDuplicate(arr) {
const map = new Map(a); arr.forEach(value= > map.set(value, value) );
return Array.from( map.values() ); // return [ ...map.values() ];
}
const arr = [NaN.1[1], [1].1.'1'.4.1.2.4.5.5.NaN.NaN.null.null.undefined.undefined];
deleteDuplicate( arr );
// [NaN, 1, Array(1), Array(1), "1", 4, 2, 5, null, undefined]
// The Map traversal order is the insertion order
Copy the code
- Set version
function deleteDuplicate(arr) {
const set = new Set( arr );
return Array.from( set ); // return [ ...set ];
}
deleteDuplicate( arr );
//[NaN, 1, Array(1), Array(1), "1", 4, 2, 5, null, undefined]
Copy the code
Promise.all
Promise._all = function (promises) {
return new Promise(function(resolve, reject) {
if (!Array.isArray(promises)) {
return reject(new TypeError('arguments must be an array'));
}
const len = promises.length;
let cnt = 0;
let res = [];
for(let i = 0; i < len; i++) {
Promise
.resolve(promises[i])
.then(function(value) {
cnt++;
res[i] = value;
if (cnt === len) {
returnresolve(res); }},function(reason) {
returnreject(reason); }); }}); };Promise._all([1.2.3.4]);
// Promise {<resolved>: Array(4)}
Promise._all([1.2.3.4]).then(res= > console.log(res));
// [1, 2, 3, 4]
Promise._all([1.2.3.Promise.reject('error')]);
// Promise {<rejected>: "error"}
Promise._all([1.2.3.Promise.reject('error')]).catch(reason= > console.log(reason));
// error
Copy the code
Examine design patterns
Subscription publishing model
Mitt: Minimal event monitoring
function mitt(all/*: EventHandlerMap*/) {
all = all || Object.create(null);
return {
on(type/*: string*/, handler/*: EventHandler*/) {
(all[type] || (all[type] = [])).push(handler);
},
off(type/*: string*/, handler/*: EventHandler*/) {
if (all[type]) {
all[type].splice(all[type].indexOf(handler) >>> 0.1);
}
},
emit(type/*: string*/, evt/*: any*/) { // * Subscribes to all event messages
(all[type] || []).slice().map((handler) = > { handler(evt); });
(all[The '*'[]] | |).slice(a).map((handler) = >{ handler(type, evt); }); }}; }const m = mitt();
m.on('hello', (name) => console.log('hello ' + name));
m.emit('hello'.'world');
Copy the code
Examination algorithm
Deep copy
Vuex version
/** * Get the first item that pass the test * by second argument function * * @param {Array} list * @param {Function} f * @return {*} */
export function find (list, f) {
return list.filter(f)[0]}/** * Deep copy the given object considering circular structure. * This function caches all nested objects and its copies. * If it detects circular structure, use cached copy to avoid infinite loop. * * @param {*} obj * @param {Array
export function deepCopy (obj, cache = []) {
// just return if obj is immutable value
if (obj === null || typeofobj ! = ='object') {
return obj
}
// if obj is hit, it is in circular structure
const hit = find(cache, c => c.original === obj)
if (hit) {
return hit.copy
}
const copy = Array.isArray(obj) ? [] : {}
// put the copy into cache at first
// because we want to refer it in recursive deepCopy
cache.push({
original: obj,
copy
})
Object.keys(obj).forEach(key= > {
copy[key] = deepCopy(obj[key], cache)
})
return copy
}
Copy the code
DFS permutations
Input 'ABC' Output ABC ACB BAC BCA CAB CBACopy the code
const str = 'abc';
const len = str.length;
const flag = [];
const res = [];
DFS(0);
// cur indicates the cur character
// There are len methods for each digit
function DFS(cur) {
if(cur === len)
return console.log(res.join(' '));
for(let i = 0; i < len; i++) {
if(! flag[i]) { res[cur] = str[i]; flag[i] =true;
DFS(cur + 1);
flag[i] = false; }}}Copy the code
Fast row
function swap(arr, i, j) {
if(i === j) return;
let tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
function quicksort(arr, s, e) {
if( s >= e ) return;
const r = s + Math.floor( (e - s) / 2 );
// Select the middle digit r(optionally) as the first digit
swap(arr, s, r);
// Find where the selected number should be in the array
// If the value is less than, the position is moved one bit later
let m = s, j = s + 1;
for(; m < e && j < e; j++) {
if(arr[j] < arr[s]) { swap(arr, ++m, j); }}// find the order bit of r
swap(arr, s, m);
// Sort recursively left and right
quicksort(arr, s, m);
quicksort(arr, m + 1, e);
}
let arr = [2.7.3.4.1.8.6];
quicksort(arr, 0, arr.length);
Copy the code
Examine the regular and replace skills
Count money format
'99999999'.replace(/ \ d {1, 3} (? =(\d{3})+$)/g.'$&,);
// The antD example
'99999999'.replace(/\B(? =(\d{3})+(? ! \d))/g.', ');
// Non-regular version
function money(str) {
const len = str.length;
let start = len % 3 || 3;
let arr = [str.slice(0, start)];
while(start < len) {
arr.push( str.slice(start, start + 3)); start +=3;
}
return arr.join(', ')}Copy the code
Blank the beginning and end
'12, 34, 5, 6'.replace(/^\s+|\s+$/g.' ');
Copy the code
Adjacent characters are de-duplicated
'aaabbbcdfgghhjjkkk'.replace(/([A-Za-z]{1})(\1)+/g.'$1');
Copy the code
Capitalize the first letter
' hi man good luck '.replace(/\w+/g.function(word) {
return word.substr(0.1).toUpperCase() + word.substr(1);
});
Copy the code