• 用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

  • 相关阅读:
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    HDU 6143 Killer Names【dp递推】【好题】【思维题】【阅读题】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    POJ 3974 Palindrome【manacher】【模板题】【模板】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6127 Hard challenge【计算机几何】【思维题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 6129 Just do it【杨辉三角】【思维题】【好题】
    HDU 3037 Saving Beans【Lucas定理】【模板题】【模板】【组合数取余】
    8.Math 对象
  • 原文地址:https://www.cnblogs.com/blfbuaa/p/7110641.html
Copyright © 2020-2023  润新知