一个小案例告诉你bind是如何改变this的

451 阅读3分钟

写在前面

我们都知道改变this指向有call,apply,bind三种方法。这篇文章就主要讲一讲bind同前面两种的区别和bind方法的一个小案例。

bind的特性

bind可以改变this的指向,但是他不会去执行这个函数,什么意思呢?我们来看代码

  • 例1
var futher = function (name){
    this.name = name;
},
function son (){
    console.log(this);
}
son.bind(futher)

在这个例子里面并不会让son函数执行,这是bind的特性之一。但是son里面的this指向了futher,这是bind的特性之二。

  • 例二
       var o = {
           name: 'andy'
       };

       function fn(a, b) {
           console.log(this);
           console.log(a + b);
       };
       var f = fn.bind(o, 1, 2);
       f();

bind会有一个返回值,这个返回值是改变this后返回的新函数。这个例子里面bind首先将fn函数里面的this指向o对象。然后参数1,2传递给了fn函数里面的a和b。然后执行f函数,this打印结果是o对象,a+b结果是3。

小tip:

bind的第三个特性是返回一个新函数,这与第1个特性不执行函数不矛盾,上面的例子我们用f接收了这个新函数再执行才有了结果哦。

bind特性的总结

我们简单总结一下,bind有3个特点。

  • 第一函数不执行。
  • 第二是bind里面的第一个参数就代表了this。
  • 第三个是会返回一个改变了this的新函数。

bind案例实战

案例功能

我们有一组按钮,点击某个按钮后为了防止多次点击使按钮禁用。三秒后再开启按钮。

案例代码

 // 4. 我们有一个按钮,当我们点击了之后,就禁用这个按钮,3秒钟之后开启这个按钮
        // var btn1 = document.querySelector('button');
        // btn1.onclick = function() {
        //     this.disabled = true; // 这个this 指向的是 btn 这个按钮
        
        //     setTimeout(function() {
        //         btn1.disabled = false; // 此时定时器函数里面的this 指向的是btn
        //     }, 3000)
        // }

在这个例子里,我们通过选择器获取到了按钮,在点击事件发生后执行的函数里面,先通过disabled让button禁用。然后设计一个定时器,我们知道在定时器里面的this指向的是window,所以this.disabled = false会报错滴,于是乎改成了btn1.disabled。但是这样写不够优雅,假如我们的按钮变量名修改了那么计时器里面的操作也要随着更改。那么如何优化呢? 我们可以在定时器外面var that= this;定时器里面函数that.disabled= false.

如何让定时器函数里面的this指向按钮而不是btn呢,我们可以利用call,apply,bind改变this。

利用bind优化案例代码

我们知道改变this前面说了三种关键字,那么用哪种更好呢,毫无疑问bind比较合理。因为bind不仅改变了this而且不会立即调用函数。而是通过定时器去触发这个函数。代码如下

       var btns = document.querySelectorAll('button');
        for (var i = 0; i < btns.length; i++) {
            btns[i].onclick = function() {
                this.disabled = true;
                setTimeout(function() {
                    this.disabled = false;
                }.bind(this), 3000);//这个this指向的是btn对象
            }
        }

定时器函数里面的this指向的是window,而bind不在定时器函数里面,在btn.onclick函数里面,所以bind(this)中的this是btn对象。当某个btn对象被点击的时候,让disabled生效,三秒后执行定时器函数,bind的特性是函数不会立即执行,所以让定时器函数内部的this变成btn后三秒后再执行,dispaled失效解除禁用。

最后的总结

通过这个案例可以很好地知道bind是如何改变this的以及他的三个特性。特别是与call,aply不一样的一个点是不会立即执行这个函数。

所以bind方法适用于不立即执行函数且需改变this的情况下。

ending...