Function bind

本文详细阐述了JavaScript bind函数的重要性和用途,通过实例展示了如何在回调函数中解决this上下文改变的问题,并提供了两种解决方案:使用self变量保存上下文作用域和通过原生bind方法或自定义兼容所有浏览器的bind拓展方法。最后,通过一个应用场景说明了bind函数在实际开发中的应用,强调了充分利用JavaScript apply方法的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天的主题是写JS function bind函数

那么为什么要讲bind呢,因为其重要性是非常之大的,非常之实用的。

bind方法主要是在回调函数this上下文发生改变的时候使用,意思是将函数绑定到当前作用域对象上。

new init();
function init(){
        $.ajax({
             url:"data.json",
              success: function(data){ //注意success是一个回调函数,关于回调函数我在之前博客里讲过,

                                                           //回调函数的时候,上下文会发生改变.
                    console.log(this); //这个this对象既不是init对象也不是window对象,而是一个jquery封装的一个对象。
                    this.createUI(data);//调用createUI时,会报错undefined is not a function ,没有createUI这个方法。
                }
       });

      this.createUI = function(data){
                console.log(data);
                alert(data);
       }
}


解决办法1

用self变量来保存上下文作用域,在回调函数(点击查看)那一节里我讲过:

new init();
function init(){

       var self = this;//保存作用域
        $.ajax({
             url:"data.json",
              success: function(data){ 
                    self .createUI(data);
                }
       });

      this.createUI = function(data){
                console.log(data);  //成功执行,输出了返回值。
       }
}

问题虽然解决了,可是每次都用var self= this;来操作,感觉不是很好看呀,这个解决办法并不完美耶。

那么好,我们再来用我们的function bind来尝试下吧,

2原生bind解决办法

关于原生的Function.prototype.bind基本支持浏览器IE8+ 和Chrome, Firefox, Opera,safari。

new init();
function init(){

        $.ajax({
             url:"data.json",
              success: function(data){ 

                    console.log(this); //output > init object .
                    this.createUI(data);

                }.bind(this) //将匿名function bind到this(init)对象上。
       });

      this.createUI = function(data){
                console.log(data);  //我很幸福激动的告诉你,成功执行,输出了返回值。
       }
}


可是这个bind方法并不兼容所有的浏览器呀,这确实是个头疼的事情。

这么方便简洁的功能,有那么些变态浏览器,就是不给力。

那么为了解决这个不给力的问题,我们也有招去兼容所有浏览器。

3兼容所有浏览器的bind拓展解决办法:

首先讲解几个知识点:

1,关于function中的arguments对象,它是一个长得像数组的东西(它也可以遍历),但是arguments不是数组,无法对数组使用标准的数组方法。在这个bind方法里它的值包括function.bind(this)中的this(init)对象等。

2,既然不是一个数组,那么我们要把他转化成一个真正的数组,转化方法:Array.prototype.slice.call(arguments);

以下开始我们的code:

Function.prototype.bind = function() {
            var __method = this;//this是一个function,就是ajax里的success:function()
            var args = Array.prototype.slice.call(arguments); //转化成数组。
            var object=args.shift(); //删除第一个值,返回被删除值(this(init)对象)。原数组的值发生改变。
            return function() {
                return __method.apply(object,
                        args.concat(Array.prototype.slice.call(arguments)));
            }
            //解析这个return步骤的意思:
            // object是bind(this,2,3)方法里的参数
            // Array.prototype.slice.call(arguments)的值是success里的回调参数。

            // __method.apply()第一个参数就是我们的this对象,第二个参数就是bind(this,2,3)和success;function(4,5)

            //的参数合并的一个数组[2,3,4,5],

            //apply会把这个数组给拆分成2,3,4,5

};

使用方法:将这个拓展的bind方法代码复制到页面引入的所有js的最前面,重新定义覆盖了原生的bind,这样任何地方都能共享这个方法。一般我们都放在commn.js里面

举例:

bind不带参数

 new init();
 function init(){
       $.ajax({
             url:"data.json",
             success: function(data){ //data是ajax的返回值
                    this.createUI(data);
             }.bind(this)
     });

     this.createUI = function(data){
            alert(data); //output 返回值
     }

}

bind带参数:

 new init();
 function init(){
       $.ajax({
             url:"data.json",
             success: function(d1,d2,data){//data是ajax的返回值
                    alert(d1+d2);
                    this.createUI(data);
             }.bind(this,"2","3") //这2和3将会传给d1,d2
     });

     this.createUI = function(data){
            alert(data); //output 返回值
     }

}


一个应用场景:

new test();
function test(){
       this.clickHandler = function(index,id){
              alert(index+id);//输出完全正确
       }
       var elements = $(".div");
       for(var i=0; i<elements.length; i++){
             var id = elements[i].id;
             elements[i].onclick = this.clickHandler.bind(this,i,id);  //这个也能用立即执行函数( 点击查看)来解决
       }

}

写到这里基本结束了,看其原理也就是充分利用了javascript的apply方法。关于这个用法我都写有文章,请各位阅读。

点击查看apply

点击查看回调函数





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值