美文网首页
理解JavaScript的Bind(翻译)

理解JavaScript的Bind(翻译)

作者: ivanStronger | 来源:发表于2017-06-05 14:33 被阅读110次

    初学JavaScript时,你可能最不想关心的就是函数绑定。不过当遇到一个经典问题,如何在另外一个函数中保持this指针。这个时候,你会明白Function.prototype.bind()是一个解决办法。

    第一次遇到这个问题的时候,你可能更倾向于通过一个变量来持有this,这样即使更换了函数的context(上下文),依然可以成功调用函数。许多人会用self,_this,甚至context作为这个变量名,我常见的是that。这个方式没有问题,不过相比较bind更赞。

    我们到底要解决什么问题?

    下面一段代码

    var myObj = {
    
        specialFunction: function () {
    
        },
    
        anotherSpecialFunction: function () {
    
        },
    
        getAsyncData: function (cb) {
            cb();
        },
    
        render: function () {
            var that = this;
            this.getAsyncData(function () {
                that.specialFunction();
                that.anotherSpecialFunction();
            });
        }
    };
    
    myObj.render();
    

    上面的代码是正确的,如果直接使用this.specialFunction,函数已经失去了当前上下文,然后就会收到以下错误

    Uncaught TypeError: Object [object global] has no method 'specialFunction'
    

    注意:严格模式,此种情况上下文为undefined

    为了能让specialFunction正常调用,我们需要保证它在被调用时候context是指向的myObj对象。使用that.specialFunction()能让我们持有context并正确调用函数。

    修改部分代码:

    render: function () {
    
        this.getAsyncData(function () {
    
            this.specialFunction();
    
            this.anotherSpecialFunction();
    
        }.bind(this));
    
    }
    

    刚刚做了什么

    bind()会返回一个新的函数。使用时,可以把this作为参数传进去,那么返回的新函数就和this绑定在一起了。在结合上面的代码,我们传了this(就是myObj)和函数绑定在一起,这是我们希望的context。然后等到函数执行的时候,this就会指向myObj对象。
    如果对bind内部实现有兴趣,可以看下下面的代码。

    Function.prototype.bind = function (scope) {
        var fn = this;
        return function () {
            return fn.apply(scope);
        };
    }
    

    观察apply的函数定义,fun.apply(thisArg, [argsArray])它的第一个参数就是函数的上下文。

    下面有一个非常简单的bind使用例子

    var foo = {
        x: 3
    }
    
    var bar = function(){
        console.log(this.x);
    }
    
    bar(); // undefined
    
    var boundFunc = bar.bind(foo);
    
    boundFunc(); // 3
    

    如果不调用bind,bar的context是全局的(global scope),也就是this指针指向的window。绑定完后,bar的this指针指向foo。

    浏览器支持

    浏览器 支持版本
    Chrome 7
    Firefox (Gecko) 4.0(2)
    Firefox (Gecko) 4.0(2)
    Internet Explorer 9
    Opera 11.60
    Safari 5.1.4

    最后

    我没有逐字逐句进行翻译,其中有些内容我按照自己的理解进行了略微修改,还有些内容我直接跳过。欢迎阅读原文。
    https://www.smashingmagazine.com/2014/01/understanding-javascript-function-prototype-bind/

    相关文章

      网友评论

          本文标题:理解JavaScript的Bind(翻译)

          本文链接:https://www.haomeiwen.com/subject/qrbifxtx.html