1.The call to realize

1. Call changes this direction

2. Pass the parameters analytically

var foo = {
  value: 1
};
var value = 2;
function bar() {
  console.log(this.value);
}
// bar._call(foo);
Copy the code

In this case console.log will print out 1. That means foo has a bar method executed.

var foo = {
  value: 1.bar: bar()
};
Copy the code

How to write?

bar._call(foo, 'aa'.'bb');
Function.prototype._call = function () {
  // The incoming value is parsed first
  // Change this to the call function foo
  // foo adds a new property called bar
  ctx = arguments[0] | |window;
  ctx.fn = this;
  ctx.fn();
  delete ctx.fn;
};
Function.prototype._call2 = function (ctx, ... args) {
  // The incoming value is parsed first
  // Change this to the call function foo
  // foo adds a new property called bar
  var fn = Symbol(a); ctx = ctx ||window;
  ctx[fn] = this;
  letresult = ctx[fn](... args);delete ctx[fn];
  return result;
};
Copy the code

2. The realization of the apply

Unlike the Call implementation, the arguments passed by Apply are an array

Function.prototype._apply = function (ctx, arr) {
  var ctx = ctx || window;
  var fn = Symbol(a); ctx[fn] =this;
  var result;
  if(! arr) { result = ctx[fn](); }else{ result = ctx[fn](... arr); }delete ctx[fn];
  return result;
};
Copy the code

3. The realization of the bind

Multiple bind points to the first bind, this

The bind() method creates a new function. When the new function is called, the first argument to bind() will be this when it runs, and the subsequent sequence of arguments will be passed as its arguments before the arguments passed. (From MDN)Copy the code

1. Return a function

2. You can pass in parameters

Function.prototype._bind = function (context) {
  var self = this;
  var args = Array.prototype.slice.call(arguments.1);
  return function () {
    var bindArgs = Array.prototype.slice.call(arguments);
    self.apply(context, args.concat(bindArgs));
  };
};

/ / the third edition
Function.prototype.bind2 = function (context) {
  var self = this;
  var args = Array.prototype.slice.call(arguments.1);

  var fbound = function () {
    var bindArgs = Array.prototype.slice.call(arguments);
    // When used as a constructor, this refers to the instance and self refers to the binding function, because 'fbound.prototype = this.prototype; ', has changed fbound.prototype to the prototype of the binding function, where the result is true. When true, this points to the instance.
    When used as a normal function, this refers to the window, self refers to the binding function, and the result is false. When the result is false, this refers to the binding context.
    self.apply(this instanceof self ? this : context, args.concat(bindArgs));
  };
  // Change the return function's prototype to the binding function's prototype, and the instance can inherit the function's prototype value
  fbound.prototype = Object.create(self.prototype);
  return fbound;
};
bind = function (context) {
  var self = this;
  var args = [].slice.call(arguments.1);
  var found = function () {
    var bindArgs = [].slice.call(arguments);
    self.apply(context, args.concat(bindArgs));
  };
};
apply = function (ctx, ... args) {
  ctx = ctx || window;
  const fn = Symbol(a);// Mount the function to the object
  ctx[fn] = this;
  // Execute the function
  letresult = ctx[fn](... args);delete ctx[fn];
  return result;
};
Copy the code
A binding function can also use the new operator to create objects: this behavior is like treating the original function as a constructor. The supplied this value is ignored, and the arguments to the call are supplied to the mock function.Copy the code

4. The new implementation

  • Returns a new object,
  • Point the prototype of the instance to the prototype of the constructor
  • This points to the instance itself
// Pass the constructor as an argument
function New(func) {
  // Declare an intermediate object, which is the final instance returned
  var res = {};
  if(func.prototype ! = =null) {
    // Point the instance's prototype to the constructor's prototype
    res.__proto__ = func.prototype;
  }
  // ret is the result of the constructor's execution
  // Point this of the constructor to this of the instance object res
  const ret = func.apply(res, [].slice.call(arguments.1));
  if ((typeof ret === 'object' || typeof ret === 'function') && ret ! = =null) {
    return ret;
  }
  return res;
}

function Person(name, age) {
  this.name = name;
  this.strength = 60;
  this.age = age;
  return {
    name: name,
    time: 80
  };
  return 'aaa';
}
var student = New(Person, 'tom');
Copy the code

If the constructor returns an object or function, only properties in the returned object can be accessed in the student instance.

If a string is returned, no value is returned

5. Instanceof implementation

function _instanceof(left, right) {
  if (typeofleft ! = ='object' || left === null) {
    return false;
  }
  let proto = Object.getPrototypeOf(left);
  while (true) {
    if (proto === null) return false;
    if (proto == right.prototype) return true; proto = proto.prototype; }}Copy the code

6. Promise

class MyPromise {
  constructor(executor) {
    this.thencallback = undefined;
    this.rejectcallback = undefined;
    this._value = undefined;
    this._status = 'pending';
    executor(this._resolve.bind(this), this._reject.bind(this));
  }
  _resolve(value) {
    setTimeout(() = > {
      this.thencallback(value);
    });
  }
  _reject(value) {
    setTimeout(() = > {
      this.rejectcallback(value);
    });
  }
  then(then_cb, onRejected) {
    this.thencallback = then_cb;
    this.rejectcallback = onRejected;
  }
  catch(onrejected) {
    this.then(null, onrejected); }}Promise.resolve = function (value) {
  if (value instanceof Promise) return value;
  // If thenable is used
  if (value && value.then && isFunction(value.then)) return new Promise(value.then);
  return new Promise(resolve= > resolve(value));
};
Promise.reject = function (value) {
  return new Promise((null, reject) = > reject(value));
};
Promise.all = function (promises) {
  let i = 0;
  let returnList = [];
  return new Promise((resolve, reject) = > {
    for (let i = 0; i < promises.length; i++) {
      // If there is an error then all. All also enters reject
      promises[i].then(data= > {
        procssData(num, data);
      }, reject);
    }
    function procssData(num, data) {
      i++;
      // The order of the arrays must correspond
      returnList[num] = data;
      // Return if the number of the token is equal to the length
      if(i === promises.length) { resolve(returnList); }}}); };Promise.race = function (promises) {
  return new Promise((resolve, reject) = > {
    for (let i = 0; i < promises.length; i++) { promises[i].then(resolve, reject); }}); };Copy the code

7. Anti shake and throttle

Image stabilization

Events are executed after a certain period of time, and if they are triggered again within that time, the timer is reset

function debounce(fn, time = 300) {
  let timer = null;
  return function (. args) {
    if (timer) clearTimeout(timer);
    timer = setTimeout(() = > {
      fn.apply(this, args);
    }, time);
  };
}
debounce(() = > {
  console.log(11);
}, 1000);
Copy the code

The throttle

Events will only be taken off once at a time, like a bus every 10 minutes, for click time

function throttle(fn, time = 1000) {
  let last = 0;
  return function (. args) {
    let now = Date.now();
    if (now - last < time) return;
    last = now;
    fn.apply(this, args);
  };
}
Copy the code

Merge optimization

Sometimes a long time of anti – shake will result in no execution at all, and must be executed once in a while

function cover(fn, delay) {
  let timer = null;
  let last = 0;
  return function (. args) {
    let now = +new Date(a);if (now - last < delay) {
      if (timer) clearTimeout(timer);
      timer = setTimeout(() = > {
        last = now;
        fn.apply(this, args);
      }, delay);
    } else {
      last = now;
      fn.apply(this, args);
// Each trigger clears the previous timer and starts executing the new timer

` ``js function deounce(func, wait) { let timer; return function () { let arg = arguments; if (timer) clearTimeout(timer); timer = setTimeout(func.apply(this, arg), wait); }; }Copy the code

8. Deep and shallow copies

Shallow copy

function shallowCopy(obj) {
  if (typeofobj ! = ='object') return obj;
  let newObj = obj.constructor === Array ? [] : {};
  for (key in obj) {
    if(obj.hasOwnProperty(key)) { newObj[key] = obj[key]; }}return newObj;
}
/ / copy
Copy the code

9. for in \ for of

The for of loop is used to get the value in a key-value pair, while the for in loop gets the key name

A data structure that deploys the symbol. iterator attribute is considered to have an iterator interface and can use the for of loop.

  • Arrays Array, Map, Set, String, arguments objects, and Nodelist objects can all be looping values with for of

10. Array method implementation

map

arr.map((item, index) = > {});
Array.prototype._map = function (fn, context) {
  var temp = [];
  if (typeof fn == 'function') {
    for (let i = 0; i < this.length; i++) {
      temp.push(fn.call(context, this[i], i, this)); }}else {
    console.log('TypeError' + fn + 'is not a function'); }};Copy the code

reduce

promise

// Simplified version

class Promise {
  constructor(executor) {
    this.thenCb = null;
    this.rejectCb = null;
    executor(this._resolve.bind(this), this._reject.bind(this));
  }
  _resolve(value) {
    setTimeout(() = > {
      this.thenCb(value);
    }, 0);
  }
  _reject(value) {
    setTimeout(() = > {
      this.rejectCb(value);
    }, 0);
  }
  then(onResolved, onRejected) {
    this.thenCb = onResolved;
    this.rejectCb = onRejected;
  }
  catch(onRejected) {
    this.then(null, onRejected); }}Copy the code