美文网首页
JS模拟实现bind,call,apply

JS模拟实现bind,call,apply

作者: Mica_马超 | 来源:发表于2021-06-08 08:58 被阅读0次

call

Function.Prototype.myCall = function(context) {
  // this 参数可以传 null,当为 null 的时候,视为指向 window
  const context = context || window;
  context.fn = this;
  // 对参数进行处理
  const args = [];
  for(let i = 1, len = arguments.length; i < len; i++) {
    args.push(arguments[i]);
  }
  let result = arguments.length > 0 ? context.fn(...args) : context.fn();
  delete context.fn;
  return result;
}

apply

Function.Prototype.myApply = function(context, arr) {
  // this 参数可以传 null,当为 null 的时候,视为指向 window
  const context = context || window;
  context.fn = this;
  let result = arr.length > 0 ? context.fn(...arr) : context.fn();
  delete context.fn;
  return result;
}

bind

简单实现

Function.prototype.myBind = function(context){
  self = this;  //保存this,即调用bind方法的目标函数
  return function(){
    return self.apply(context, [...arguments]);
  };
};

函数柯里化的实现

Function.prototype.myBind = function(context){
  // 使用闭包存下初始参数
  const args = Array.prototype.slice.call(arguments, 1),
  self = this;
  return function() {
     // 再次调用时
    const innerArgs = Array.prototype.slice.call(arguments);
    const finalArgs = args.concat(innerArgs);
    return self.apply(context,finalArgs);
  };
};

构造函数的实现

Function.prototype.myBind = function(context){
  // 判断是否为函数
  if(typeof this !== 'function') {
    throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
  }
  const args = Array.prototype.slice(arguments, 1);
  self = this;
  bound = function() {
    const innerArgs = Array.prototype.slice.call(arguments);
    const finalArgs = args.concat(innerArgs);
    // 判断this,如果是,则传递this即实例化的对象。
    return self.apply((this instanceof F ? this : context), finalArgs);
  };
  // 处理原型链
  let F = function(){};
  F.prototype = self.prototype;
  bound.prototype = new F();

  retrun bound;
};

ES6实现

Function.prototype.myCall = function (context, ...args) {
  context = context || window;

  const fnSymbol = Symbol("fn");
  context[fnSymbol] = this;

  const result = context[fnSymbol](...args);
  delete context[fnSymbol];
  return result;
}

结合实现

Function.prototype.myBind = function(context, ...args){
  self = this;
  return function() {
    context = context || window
    const fnSymbol = Symbol('fn')
    context.fnSymbol = self

    const result = context[fnSymbol](...args)
    delete context[fnSymbol]
    return result
  };
};

相关文章

网友评论

      本文标题:JS模拟实现bind,call,apply

      本文链接:https://www.haomeiwen.com/subject/jsakeltx.html