详解JavaScript函数绑定


Posted in Javascript onAugust 18, 2013
<body>    <input id="btnTest" type="button" value="Button"/>
        <script type="text/javascript">            
            var handler={
                message:"Event handled.",
                handlerFun:function(){
                    alert(this.message);
                }
            };
            document.getElementById('btnTest').onclick=handler.handlerFun;
        </script>
    </body>

上面的例子创建了一个handler对象,handler.handlerFun()方法被分配为DOM按钮的click事件处理程序。设计意图是这样的:当点击按钮的时候触发该方法,弹出对话框显示handler定义的message,然而点击后对话框内容却是undefined。熟悉闭包的同学可以轻松看出来这个问题在于没有保存handler.handlerFun()方法的执行环境,this对象最后指向了DOM按钮而非handler。可以使用闭包解决此问题,修改函数绑定语句
document.getElementById('btnTest').onclick=function(){
                handler.handlerFun();
            }

这样就可以得到预期的结果,这个解决方案在onclick程序内部使用一个闭包直接调用handler.handlerFun()方法,当然这是特定于此场景的解决方案,创建多个闭包可能会令代码难以理解和调试。

自定义bind函数

function bind(fn,context){
                return function(){
                    return fn.apply(context,arguments);
                };
            }            document.getElementById('btnTest').onclick=bind(handler.handlerFun,handler);

通过自定义的bind函数可以将函数绑定到指定环境,bind()函数接收两个参数:一个绑定函数,一个执行环境,并返回一个在执行环境中调用绑定函数的函数。看起来很简单,但是其功能很强大,在bing()中创建了一个闭包,闭包使用apply()调用传入的函数,并给apply()传入执行环境和参数,这里的arguments是内部匿名函数的,而非bind()的。当调用返回的函数时,它会在给定的函数中执行被传入的函数,并给出所有参数。上面例子的调用handler.handlerFun依旧可以得到参数event,因为所有参数在都通过绑定的函数传递给它了。

小结

一旦要将某个函数以函数指针的形式传递,同时该函数必须在特定的环境中执行,自定义的bind()函数就可以使用,他们主要用于事件处理程序及setTimeout和setInterval,然而这种绑定方式和普通函数相比需要更多的内存开销,所以尽量只在必要的时候使用。

Javascript 相关文章推荐
zeroclipboard复制到剪切板的flash
Aug 04 Javascript
jQuery+CSS 实现随滚动条增减的汽水瓶中的液体效果
Sep 26 Javascript
JS获取Table中td值的方法
Mar 19 Javascript
Javascript技术栈中的四种依赖注入详解
Feb 23 Javascript
jQuery on()方法绑定动态元素的点击事件实例代码浅析
Jun 16 Javascript
关于JS 预解释的相关理解
Jun 28 Javascript
js实现文字选中分享功能
Jan 25 Javascript
node vue项目开发之前后端分离实战记录
Dec 13 Javascript
原生javascript单例模式的应用实例分析
Feb 23 Javascript
在Vuex中Mutations修改状态操作
Jul 24 Javascript
js实现飞机大战游戏
Aug 26 Javascript
Vue实现简单计算器
Jan 20 Vue.js
jQuery 绑定事件到动态创建的元素上的方法实例
Aug 18 #Javascript
jQuery焦点图切换特效插件封装实例
Aug 18 #Javascript
JavaScript生成GUID的多种算法小结
Aug 18 #Javascript
实测jquery data()如何存值
Aug 18 #Javascript
js兼容的placeholder属性详解
Aug 18 #Javascript
JQuery分别取得每行最后一列和最后一行的示例代码
Aug 18 #Javascript
jquery验证表单中的单选与多选实例
Aug 18 #Javascript
You might like
php中批量修改文件后缀名的函数代码
2011/10/23 PHP
php不用正则验证真假身份证
2013/11/06 PHP
smarty模板局部缓存方法使用示例
2014/06/17 PHP
PHP中new static()与new self()的区别异同分析
2014/08/22 PHP
php通过function_exists检测函数是否存在的方法
2015/03/18 PHP
php计算多维数组中所有值总和的方法
2015/06/24 PHP
thinkphp中U方法按路由规则生成url的方法
2018/03/12 PHP
php的命名空间与自动加载实现方法
2019/08/25 PHP
Javascript 中介者模式实例
2009/12/16 Javascript
js转化毫秒为时间格式代码
2014/04/10 Javascript
了不起的node.js读书笔记之node.js中的特性
2014/12/22 Javascript
Nodejs如何搭建Web服务器
2016/03/28 NodeJs
JS实现兼容各种浏览器的高级拖动方法完整实例【测试可用】
2016/06/21 Javascript
老生常谈javascript的类型转换
2016/10/12 Javascript
js 调用百度分享功能
2017/02/27 Javascript
js css3实现图片拖拽效果
2017/03/04 Javascript
使用jQuery给Table动态增加行、清空table的方法
2018/09/05 jQuery
Vue中props的详解
2019/05/16 Javascript
[38:39]完美世界DOTA2联赛循环赛 IO vs GXR BO2第二场 11.04
2020/11/05 DOTA
Python多线程学习资料
2012/12/19 Python
Python中几个比较常见的名词解释
2015/07/04 Python
总结用Pdb库调试Python的方式及常用的命令
2016/08/18 Python
Python做简单的字符串匹配详解
2017/03/21 Python
JSON文件及Python对JSON文件的读写操作
2018/10/07 Python
Django unittest 设置跳过某些case的方法
2018/12/26 Python
Python 3.x基于Xml数据的Http请求方法
2018/12/28 Python
解决Python3 控制台输出InsecureRequestWarning问题
2019/07/15 Python
Python 画出来六维图
2019/07/26 Python
浅谈pytorch中的BN层的注意事项
2020/06/23 Python
意大利一家专营包包和配饰的网上商店:Borse Last Minute
2019/08/26 全球购物
Linux面试题LINUX系统类
2015/11/25 面试题
中学生获奖感言
2014/02/04 职场文书
银行给客户的感谢信
2015/01/23 职场文书
2015年幼儿园学前班工作总结
2015/05/18 职场文书
2019年幼儿园家长接送责任书
2019/10/29 职场文书
nginx日志格式分析和修改
2022/04/28 Servers