ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

bind,call,apply模拟实现

2020-09-13 13:00:41  阅读:198  来源: 互联网

标签:function bind call context var apply prototype fn


首先,三者第一个参数都为this指向

区别

bind返回的是一个函数体

call和apply会直接执行,但是call参数需要一个一个进行传递,apply的第二个参数是一个数组

实现

bind

简单实现

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

考虑到函数柯里化的实现

Function.prototype.myBind = function(context){
  // 使用闭包存下初始参数
  var args = Array.prototype.slice.call(arguments, 1),
  self = this;
  return function() {
        // 再次调用时
      var innerArgs = Array.prototype.slice.call(arguments);
      var 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');
  }
  var args = Array.prototype.slice(arguments, 1);
  self = this;
  bound = function() {
      var innerArgs = Array.prototype.slice.call(arguments);
      var 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;
};

call

思路

// 要实现这个效果
var foo ={
  value:1
}
function bar(){
  console.log(this.value)
}
bar.call(foo);//1

// 相当于做如下事情
var foo = {
    value: 1,
    bar: function() {
        console.log(this.value)
    }
};
foo.bar(); // 1

​实现

Function.Prototype.myCall = function(context) {
  // this 参数可以传 null,当为 null 的时候,视为指向 window
  var context = context || window;
    context.fn = this;
  // 对参数进行处理
    var args = [];
  for(var 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
  var context = context || window;
    context.fn = this;
  let result = arr.length>0 ? context.fn(...arr) : context.fn();
  delete context.fn;
  return result;
}

参考自

MDN中对bind的实现

https://blog.csdn.net/weixin_34250709/article/details/92426126

https://zhuanlan.zhihu.com/p/48081913

标签:function,bind,call,context,var,apply,prototype,fn
来源: https://www.cnblogs.com/suihang/p/13661021.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有