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} cache * @return {*} */
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