zoukankan      html  css  js  c++  java
  • 了解.apply与.call以及.bind

    1.apply:foo.apply(obj,args)方法能接收两个参数:

         (1)obj:这个对象将代替Function类里this对象;

         (2)args:这个是数组,它将作为参数传给Function(args-->arguments);

      关于apply,我所知道的用法中,最经典的莫过于巧妙地实现提取数值(Number)数组最值的方法:

    Array.prototype.getMin = function() {
      return Math.min.apply(null, this);
    };
    var arr = [1,2,3,4,5,213212,-99];
    arr.getMin();//-99

    2.call: foo.call(obj, args);

    对于apply与call不同点的说明:A for array and C for comma;call的参数只能一个一个地传递;

    3.bind()方法会创建一个新函数,当这个新函数被调用时,它的this值是传递给bind()的第一个参数, 它的参数是bind()的其他参数和其原本的参数.

      绑定函数示例:参考网址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

    this.x = 9; 
    var module = {
      x: 81,
      getX: function() { return this.x; }
    };
    
    module.getX(); // 81
    
    var retrieveX = module.getX;
    retrieveX(); // 9, because in this case, "this" refers to the global object
    
    // Create a new function with 'this' bound to module
    //New programmers (like myself) might confuse the global var getX with module's property getX
    var boundGetX = retrieveX.bind(module);//<<--------bind的第一个参数为this指向的对象
    boundGetX(); // 81

      复制某个对象下的方法之后想要this仍然指向module对象,获取它的属性X值,如上文代码中的:var retrieveX = module.getX;

    但是在直接调用复制出来的函数retrieveX时,注意它是在全局作用域下直接内调用的,那么此时的this指向window,所有无法像我们“想当然地”认为的那样取出module对象下的属性值;

      而bind拥有改变函数执行时的作用域的作用(apply与call同样拥有这样的作用),我们可以在调用时使用bind方法,并将bind的第一个参数设置为module对象,那么我们就改变了this的指向(指向module),此时我们就可以达到预期的目的了。

      关于.call、.bind的基本知识看完了?懂了吗?来个思考题检验一下你是否理解了这些方法.

    问:下面的代码输出的是什么?

    分析:

    1.首先test函数输出的是操作对象(this指向)的a属性的值;所以接下来的思路就是判断this的指向;

    2.三个var语句,定义了两个对象,一个绑定函数.

      对象

        var obj1= {a:1};

        var obj2 = {a:2};

      绑定函数

        var fn = test.bind(obj2);//绑定函数作用域内this指向obj2;

    最后关键的执行语句test.bind(obj2).call(obj1);//call的第一个参数传递的也是this的指向那么问题来了,this到底指向哪个对象?

    结果:如果你回答输出的a1那就错了,因为通过bind取得的函数是个闭包,在调用时,只会通过闭包作用域找到之前存在的值(不是this),所以用call(其只改变this)是无法改变它的结果。输出为2.


    进一步进行如下测试:

    let aa = function() {
       console.log(this.n);
       console.log(arguments);
    };
    let testObj = {
       n: 1 
    };
    let bb = aa.bind(testObj, "预置的参数");
    bb.call({n:2}, "后来加入的参数一", "后来加入的参数二");

    //控制台输出的结果是:
    //1
    //["预置的参数", "后来加入的参数一", "后来加入的参数二"]

    得出的结论是:

    1. bind函数生成的新函数在生成的时候它的上下文就已经固定了,后续通过.call或者.apply等方法都无法改变它。

    2. 由预置的参数(n个) 与 后续加入的参数(n个)组成新函数执行时的arguments数组。

    editTime:2017/02/08


  • 相关阅读:
    vim编辑器替换以及全局替换
    Linux下grep显示前后几行信息
    Pymol里常用到的命令,随用随记
    硬盘里有文件错误,导致删除不了文件,可以使用如下方法
    解决Host key verification failed
    tcl语言杂记
    python脚本后台运行的几种方式
    centos设置连续登录3次密码错误自动锁定账户3分钟
    ubuntu安装显卡驱动
    虚拟交换机(OVS)之结构印象
  • 原文地址:https://www.cnblogs.com/foxNike/p/5656059.html
Copyright © 2011-2022 走看看