• 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 是闭包的变量。

  • 相关阅读:
    MSRA-TD5000数据集使用详解
    2017CS231n学习笔记——计算机视觉的概述
    函数式非凡的抽象能力
    或许是领域建模的真相
    SpringBoot+ActiveMq实现订阅模式(Topic)消息队列
    SpringBoot下Activemq自定义MessageConverter
    spring boot 2.0类找不到EmbeddedServletContainerInitializedEvent
    Error creating bean with name 'org.apache.cxf.spring.boot.autoconfigure.CxfAutoConfiguration
    Intellij IDEA使用 lambda表达式报错-source1.5中不支持lambda表达式
    SpringBoot--实战开发--commons-lang3(三十五)
  • 原文地址:https://www.cnblogs.com/pipu-qiao/p/8685647.html
Copyright © 2020-2023  润新知