• call,apply,bind 方法的学习


    这是三个常用的操作函数的方法,在js中函数就是一等公民,所以说掌握这三个方法还是有必要的

    call 和 apply,都会绑定函数的上下文(context)并立即执行调用该方法函数,两者区别在于,接受的参数格式不一样。

    call 接收的参数形式是: (context,arg1,arg2,ar3....)  // argn 是一个个具体的参数

    apply 接收的参数形式是: (context,argArr) // argArr 可以是一个有参数组成的数组或者arguments

    bind 会返回绑定调用该方法的函数上下文的新的函数。

    1.call的示例

    var a = {
      name: 'aa',
      getName: function(age) {
        return this.name + ',' + age;
      }
    };
    var b = {
      name: 'bbb'
    };
    
    a.getName.call(b,23) // bbb,23

    1.用call实现apply

    现在的我能想到的办法就是通过eval对参数进行拼接,因为函数底层操作参数的方法没有暴露(可能不知道吧)

    代码示例

    这里先看下一个eval作用域的事情,经过测试eval方法获取变量也是在划分作用域的,并不是从全局获取,示例:

    (function () {
      var me = {name: '33'};
      console.log(eval('me')); // 33
    })();

    这样我们就能拿到函数原来的上下文

    用call实现apply

    // 用个low的办法实现apply
    
    Function.prototype.fakeApply = function (context,arguments) {
      // 拼接参数
      var arg;
    
      // 如果有参数将参数转换成数组
      if(arguments){
        arg = [].slice.call(arguments,0);
        // 将数组拼接成字符串格式 ->  arg1,arg2,arg3,...
        arg = arg.join(',');
      }
    
      var excuteStr  = 'this.call(context' + (arg ?',' + arg : '' ) + ')'; // this.call(context,2,3,4)
    
      console.log(eval('this.call(context' + (arguments ?',' +  [].slice.call(arguments,0).join(',') : '' ) + ')'));
      // { name: 44 }
      // { '0': 2, '1': 3, '2': 4 }
      // ok
    };
    var a = {
      name: 'aa',
      getName: function() {
        console.log(this);
        console.log(arguments);
        return 'ok';
      }
    };
    a.getName.fakeApply({name:44},[2,3,4]);

    为了加深bind理解,下面是用apply实现bind的示例

    Function.prototype.fakeBind = function () {
      // bind 有可能会传入绑定的参数
      var prevFun = this;
      var context = arguments[0];
      var prevArg = arguments.length > 1 ? [].slice.call(arguments,1) : [] ;
    
      return function () {
        var curArg = [].concat.apply(prevArg,arguments);
        return prevFun.apply(context,curArg);
      };
    };
    var fun1 = function () {
      console.log(this);
      console.log(arguments);
    };
    
    var fun2 = fun1.fakeBind({name: 'aaa'},2,3);
    fun2(4,5);
    
    // { name: 'aaa' }
    // { '0': 2, '1': 3, '2': 4, '3': 5 }

    返回了一个新的函数,函数中的prevFun和preArg 是闭包的变量。

  • 相关阅读:
    topcoder srm 320 div1
    topcoder srm 325 div1
    topcoder srm 330 div1
    topcoder srm 335 div1
    topcoder srm 340 div1
    topcoder srm 300 div1
    topcoder srm 305 div1
    topcoder srm 310 div1
    topcoder srm 315 div1
    如何统计iOS产品不同渠道的下载量?
  • 原文地址:https://www.cnblogs.com/pipu-qiao/p/8685647.html
Copyright © 2020-2023  润新知