zoukankan      html  css  js  c++  java
  • bind,call,apply模拟实现

    首先,三者第一个参数都为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

  • 相关阅读:
    乌龟棋
    Cut the Sequence
    [NOI2001]炮兵阵地
    Fence
    环路运输
    查找并替换字符串 Find And Replace in String
    最大交换 Maximum Swap
    丑数问题 Ugly Number
    二叉树最大宽度 Maximum Width of Binary Tree
    距离为K的节点 All Nodes Distance K in Binary Tree
  • 原文地址:https://www.cnblogs.com/suihang/p/13661021.html
Copyright © 2011-2022 走看看