详解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 相关文章推荐
JavaScript高级程序设计 阅读笔记(十二) js内置对象Math
Aug 14 Javascript
javascript面向对象之对象的深入理解
Jan 13 Javascript
Javascript实现字数统计
Jul 03 Javascript
jQuery实现时尚漂亮的弹出式对话框实例
Aug 07 Javascript
jQuery Ajax Post 回调函数不执行问题的解决方法
Aug 15 Javascript
BootstrapTable请求数据时设置超时(timeout)的方法
Jan 22 Javascript
AngularJS实现自定义指令及指令配置项的方法
Nov 20 Javascript
webpack多入口文件页面打包配置详解
Jan 09 Javascript
react-redux中connect的装饰器用法@connect详解
Jan 13 Javascript
vue注册组件的几种方式总结
Mar 08 Javascript
webpack4 + react 搭建多页面应用示例
Aug 03 Javascript
解决vue 中 echart 在子组件中只显示一次的问题
Aug 07 Javascript
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
QueryPath PHP 中的jQuery
2010/04/11 PHP
php颜色转换函数hex-rgb(将十六进制格式转成十进制格式)
2013/09/23 PHP
5款适合PHP使用的HTML编辑器推荐
2015/07/03 PHP
微信公众平台开发教程⑤ 微信扫码支付模式介绍
2019/04/10 PHP
修复IE9&amp;safari 的sort方法
2011/10/21 Javascript
利用Javascript判断操作系统的类型实现不同操作系统下的兼容性
2013/01/29 Javascript
jQuery中实现动画效果的基本操作介绍
2013/04/16 Javascript
JS实现点击上移下移LI行数据的方法
2015/08/05 Javascript
JavaScript多线程详解
2015/08/12 Javascript
javascript如何实现暂停功能
2015/11/06 Javascript
javascript自动切换焦点控制效果完整实例
2016/02/02 Javascript
JavaScript实现广告弹窗效果
2016/08/09 Javascript
Vue.js实战之通过监听滚动事件实现动态锚点
2017/04/04 Javascript
解决JS内存泄露之js对象和dom对象互相引用问题
2017/06/25 Javascript
微信小程序时间戳转日期的详解
2019/04/30 Javascript
JS实现简易计算器
2020/02/14 Javascript
微信小程序开发之获取用户手机号码(php接口解密)
2020/05/17 Javascript
如何用JS模拟实现数组的map方法
2020/07/30 Javascript
js实现盒子滚动动画效果
2020/08/09 Javascript
微信小程序canvas动态时钟
2020/10/22 Javascript
python实现通过pil模块对图片格式进行转换的方法
2015/03/24 Python
如何高效使用Python字典的方法详解
2017/08/31 Python
python pyheatmap包绘制热力图
2018/11/09 Python
python 获得任意路径下的文件及其根目录的方法
2019/02/16 Python
Python列表原理与用法详解【创建、元素增加、删除、访问、计数、切片、遍历等】
2019/10/30 Python
Python 内置函数globals()和locals()对比详解
2019/12/23 Python
python 读取串口数据的示例
2020/11/09 Python
联想美国官方商城:Lenovo美国
2017/06/19 全球购物
面向中国市场的在线海淘美妆零售网站:Beauty House美丽屋
2021/03/02 全球购物
劳动竞赛活动方案
2014/02/20 职场文书
大宝sod蜜广告词
2014/03/21 职场文书
事业单位考核材料
2014/05/21 职场文书
环卫工人慰问信
2015/02/15 职场文书
思想道德自我评价2015
2015/03/09 职场文书
Unity连接MySQL并读取表格数据的实现代码
2021/06/20 MySQL
python flappy bird小游戏分步实现流程
2022/02/15 Python