zoukankan      html  css  js  c++  java
  • Javascript中bind()方法的使用与实现

    转自--https://www.cnblogs.com/chenpingzhao/p/4883995.html

    我们先来看一道题目

    var write = document.write; 
    write("hello"); 
    //1.以上代码有什么问题
    //2.正确操作是怎样的

    不能正确执行,因为write函数丢掉了上下文,此时this的指向global或window对象,导致执行时提示非法调用异常,所以我们需要改变this的指向

    正确的方案就是使用 bind/call/apply来改变this指向

    bind方法

    var write = document.write;
    write.bind(document)('hello');

    call方法

    var write = document.write;
    write.call(document,'hello');

    apply方法

    var write = document.write;
    write.apply(document,['hello']);

    bind函数

    bind()最简单的用法是创建一个函数,使这个函数不论怎么调用都有同样的this值。常见的错误就像上面的例子一样,将方法从对象中拿出来,然后调用,并且希望this指向原来的对象。如果不做特殊处理,一般会丢失原来的对象。使用bind()方法能够很漂亮的解决这个问题:

    <script type="text/javascript">
     
    this.num = 9; 
    var module = { 
        num: 81,
        getNum: function(){
            console.log(this.num);
        }
    };
     
    module.getNum(); // 81 ,this->module
     
    var getNum = module.getNum;
    getNum(); // 9, this->window or global
     
    var boundGetNum = getNum.bind(module); 
    boundGetNum(); // 81,this->module
     
    </script>

    偏函数(Partial Functions)

    这是一个很好的特性,使用bind()我们设定函数的预定义参数,然后调用的时候传入其他参数即可:

    <script type="text/javascript">
     
    function list() { 
      return Array.prototype.slice.call(arguments);
    }
     
    var list1 = list(1, 2, 3);
    console.log(list1);// [1, 2, 3]
     
    // 预定义参数37
    var leadingThirtysevenList = list.bind(undefined, 37);
     
    var list2 = leadingThirtysevenList();
    console.log(list2);// [37] 
     
    var list3 = leadingThirtysevenList(1, 2, 3);
    console.log(list3);// [37, 1, 2, 3] 
    </script>

    和setTimeout or setInterval一起使用

    一般情况下setTimeout()的this指向window或global对象。当使用类的方法时需要this指向类实例,就可以使用bind()将this绑定到回调函数来管理实例。

    <script type="text/javascript">
     
    function Bloomer() { 
      this.petalCount = Math.ceil(Math.random() * 12) + 1;
    }
     
    // 1秒后调用declare函数
    Bloomer.prototype.bloom = function() { 
      window.setTimeout(this.declare.bind(this), 1000);
    };
     
    Bloomer.prototype.declare = function() { 
      console.log('我有 ' + this.petalCount + ' 朵花瓣!');
    };
     
    var test = new Bloomer();
     
    test.bloom();
     
    </script>

    绑定函数作为构造函数

    绑定函数也适用于使用new操作符来构造目标函数的实例。当使用绑定函数来构造实例,注意:this会被忽略,但是传入的参数仍然可用。

    <script type="text/javascript">
     
    function Point(x, y) { 
     
      this.x = x;
      this.y = y;
    }
     
    Point.prototype.toString = function() { 
      console.log(this.x + ',' + this.y);
    };
     
    var p = new Point(1, 2); 
    p.toString(); // 1,2
     
    var YAxisPoint = Point.bind(null,10);
    var axisPoint = new YAxisPoint(5); 
    axisPoint.toString(); // 10,5
     
    console.log(axisPoint instanceof Point); // true 
    console.log(axisPoint instanceof YAxisPoint); // true 
    console.log(new Point(17, 42) instanceof YAxisPoint); // true  
    </script>

    上面例子中Point和YAxisPoint共享原型,因此使用instanceof运算符判断时为true

  • 相关阅读:
    解决在火狐中不支持onreadystatechange的方法
    jquery ajax与分页的实现(mvc下)
    通过ChekBox设置EditText内容是否呈现密码显示
    Android自定义dialog
    Android Intent笔记
    启动另外的一个应用程序的Activity(三种方式)(转载)
    Android代码中声明一个layout
    在Linux下创建函数库
    五分钟讲清楚UML
    QT中使用QProcess启用外部程序
  • 原文地址:https://www.cnblogs.com/exhuasted/p/8259497.html
Copyright © 2011-2022 走看看