zoukankan      html  css  js  c++  java
  • 聊聊Function的bind()

    bind顾名思义,绑定。

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

    上面这个定义最后一句有点绕,我们来理一下。

    bind()接受无数个参数,第一个参数是它生成的新函数的this指向,比如我传个window,不管它在何处调用,这个新函数中的this就指向window,这个新函数的参数就是bind()的第二个、第三个、第四个....第n个参数加上它原本的参数。(行吧,我自己都蒙圈了)

    我们还是看看栗子比较好理解,举个bind()最基本的使用方法:

    this.x = 9; 
    var module = {
      x: 81,
      getX: function() { return this.x; }
    };
    
    module.getX(); // 返回 81
    
    var retrieveX = module.getX;
    retrieveX(); // 返回 9, 在这种情况下,"this"指向全局作用域
    
    // 创建一个新函数,将"this"绑定到module对象
    // 新手可能会被全局的x变量和module里的属性x所迷惑
    var boundGetX = retrieveX.bind(module);
    boundGetX(); // 返回 81

    这里很明显,我们在window对象下调用retrieveX,得到的结果肯定是window下的x,我们把module对象绑定到retrieveX的this上,问题就解决了,不管它在何处调用,this都是指向module对象。

    还有bind()的其他参数,相信第一次接触bind()的朋友看到上面的定义都会蒙圈。

    还是举个栗子:

    function list() {
      return Array.prototype.slice.call(arguments);
    }
    
    var list1 = list(1, 2, 3); // [1, 2, 3]
    
    // 创建一个拥有预设初始参数的函数
    var leadingThirtysevenList = list.bind(undefined,[69,37],{a:2});
    
    var list2 = leadingThirtysevenList(); // [[69,37],{a:2}]
    var list3 = leadingThirtysevenList(1, 2, 3); // [[69,37],{a:2}, 1, 2, 3]

    list函数很简单,把传入的每个参数插入到一个数组里,我们用bind()给list函数设置初始值,因为不用改变list中this的指向,所以直接传undefined,从第二个参数开始,就是要传入list函数的值,list2和list3的返回值很好的说明了一切。

    我自己一般使用的bind()的场景是配合setTimeout函数,因为在执行setTimeout时,this会默认指向window对象,在使用bind()之前,我是这么做的:

        function Coder(name) {
            var that = this;
            that.name = name;
            that.getName = function() {
                console.log(that.name)
            };
            that.delayGetName = function() {
                setTimeout(that.getName,1000)
            };
        }
        var me = new Coder('Jins')
        me.delayGetName()//延迟一秒输出Jins

    在函数内顶层定义一个that缓存this的指针,这样不论怎么调用,that都是指向 Coder的实例,但是多定义一个变量总是让人不太舒服。

    使用bind()就简单多了:

        function Coder(name) {
            this.name = name;
            this.getName = function() {
                console.log(this.name)
            };
            this.delayGetName = function() {
                setTimeout(this.getName.bind(this),1000)
            };
        }
        var me = new Coder('Jins')
        me.delayGetName()//延迟一秒输出Jins

     这样就OK了,直接把setTimeout的this绑定到外层的this,这肯定是我们想要的!

    行吧,先聊这么多,坚持学习!

    最后附上参考地址:

    Function.prototype.bind()

  • 相关阅读:
    BZOJ-4010 菜肴制作 贪心+堆+(拓扑图拓扑序)
    BZOJ-3670 动物园 KMP+奇怪的东西
    3172
    BZOJ-3668 起床困难综合症 位运算+贪心
    BZOJ-2257 瓶子和燃料 分解因数+数论方面乱搞(裴蜀定理)
    BZOJ-1013 球形空间产生器sphere 高斯消元+数论推公式
    BZOJ-2186 沙拉公主的困惑 线性筛(筛筛筛)+线性推逆元
    BZOJ-2326 数学作业 矩阵乘法快速幂+快速乘
    BZOJ-1705 Longge的问题 一维GCD SUM 乱搞+质因数分解+...
    BZOJ-2875 随机数生成器 矩阵乘法快速幂+快速乘
  • 原文地址:https://www.cnblogs.com/chinajins/p/5987608.html
Copyright © 2011-2022 走看看