zoukankan      html  css  js  c++  java
  • 用bind方法保持this上下文

    近期自学JavaScript。学到bind方法这块儿有些地方不太明确。自己就查了些资料,结合自己的理解写了这篇文章以备后面回想用。

    事实上应该还是搬砖为主吧。

    什么是this对象

    先来说说什么是this对象吧。每一个函数在调用的时候都会自己主动获取两个特殊变量:this和arguments对象。

    this值详细是指哪个对象是和该函数的运行环境相关的。假设是作为对象的方法,那么this就是对象实例本身;假设是一个全局函数,那么this就是window对象。用一句话来概括,this就是调用这种方法的对象。

    保持this上下文

    有时候。我们须要保持this的上下文,也就是在一个运行环境中想要訪问到还有一个运行环境的this值。在什么时候须要这么做呢?比方说将一个对象的方法赋值给了一个全局变量,然后在全局变量中调用这种方法,那么this值就不再是原来的对象而是window对象了,然而可能我们仍须要在全局环境中依照对象的方法来调用。又比方说一个方法中包括了闭包,闭包是无法訪问到其外部函数的this对象的,由于this对象是在调用方法的时候自己主动生成,内部函数在搜索这两个变量的时候仅仅会搜索到其自身的活动对象。而不会沿着作用域链往外搜索,所以闭包訪问不到外部函数的this值。

    假设要想訪问,就应该想办法把this值传递下去。
    通常能够通过这种方式保持this上下文:在外部函数中将this缓存到一个变量中,通常变量名称使用self, _this 或者 context。那么闭包就能够通过这个可訪问的变量来获取外部函数的this值,this上下文得以保持。比方以下的代码:

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

    这里有一个对象myObj。它有一个render实例方法,在这种方法内部又调用了它的还有一个实例方法getAsyncData,而这种方法有一个新的函数作为參数,这个函数相当于是一个闭包。是不能获取到外部函数中的this值的。为了在这个闭包中也能訪问实例方法,须要获取到外部环境的this值,这里把this(this为调用render方法的对象。即实例对象myObj)缓存到了变量that中。

    此外还可通过bind方法,这就是本文所要讲述的重点。

    bind方法

    bind方法生成了一个新的函数,称为绑定函数,传入bind方法的第一个參数作为这个绑定函数的this对象,传入bind的第二个參数连同后面调用绑定函数时传入的參数依照先后顺序(传入bind的在前)构成绑定函数的參数。
    如今我们把上面的样例改动一下:

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

    .bind()创建了一个函数,当这个函数在被调用的时候。它的 this 关键词会被设置成被传入的值(这里指调用bind()时传入的參数)
    再看一个bind的使用样例:

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

    将bar方法和foo对象绑定后,bar中的this对象被替换为了foo,并生成了一个新的函数boundFunc,因此在全局环境中调用boundFunc时。也能够訪问到foo对象的属性。
    还能够了解一下Function.prototype.bind()内部是什么样的:

    Function.prototype.bind = function (scope) {
        var fn = this;//this是调用bind方法的对象(别的方法对象)
        return function () {
            return fn.apply(scope);//把fn环境中的this替换为scope
        };
    }

    可看出,bind方法返回了一个新的函数。这种方法返回了原方法(调用bind的方法)通过apply改动作用域(传入的參数scope)后的运行结果。假设调用这个新函数则会马上运行fn.apply(scope)。并返回运行后的结果。

    fn.bind()

    与call、apply的差别

    call、apply是改动函数的作用域,而且马上运行。而bind是返回了一个新的函数,不是马上运行,即call and apply call a function while bind creates a function。

    bind在回调函数中经常使用到。

    參考资料:
    理解 JavaScript 中的 Function.prototype.bind
    js中bind、call、apply函数的使用方法
    https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

  • 相关阅读:
    学长帮帮忙—Beta冲刺(4/7)
    学长帮帮忙—Beta冲刺(3/7)
    【二食堂】二食堂很难排队 博客目录
    【二食堂】Beta
    【二食堂】Beta
    【二食堂】Beta
    【二食堂】Beta
    【二食堂】Beta
    【二食堂】Beta
    【二食堂】Beta
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7110641.html
Copyright © 2011-2022 走看看