call、apply、bind

运行原理

  • 当调用fn.call/apply/bind时,首先基于fn.__proto__找到在Function.prototype.call/apply/bind把方法执行,方法中的this->fn。方法执行的作用就是:把fn[this]执行,并且让方法fn[this]中的this指向第一个传递的实参[obj]

  • fn.call()非严格模式下this默认是window[第一个参数传的是null/undefined也是window],严格模式下this->undefined[第一个参数传的是谁,this就指向谁]

call/apply/bind区别

  • call/apply这两者只是传参不一样其他都一样,call是一个个的传参;apply只有两个参数,第一个是改变的this,第二项是数组或者类数组。这两者都是把函数立即执行。
  • bind是把传入要改变this和参数预先存储起来(柯理化->闭包),不立即执行。

手写call/apply/bind

Function.prototype.call = function call(context){
  context = context || window;
  if(!/^(object|function)$/i.test(typeof context)) context = Object(context);
  let self = this,
      key = Symbol('KEY'),
      params = [...arguments].slice(1),
      result = null;
  context[key] = self;
  result = context[key](...params);
  delete context[key];
  return result;
}
Function.prototype.apply = function apply(context, arr){
  context = context || window;
  if(!Array.isArray(arr)) throw new TypeError(arr + 'must be a Array!');
  if(!/^(object|function)$/i.test(typeof context)) context = Object(context);
  let self = this,
      key = Symbol('KEY'),
      result = null;
  context[key] = self;
  result = context[key](...arr)
  deletet context[key];
  return result;
}
Function.prototype.bind = function bind(context){
  context = context || window;
 let self = this;
 let params = [...arguments].slice(1)
 return function proxy(){
   var args = [...arguments]
   params = params.concat(args);
   return self.apply(context, params)
 }
}
posted @ 2022-02-28 15:27  guyigg  阅读(51)  评论(0)    收藏  举报