详解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 鼠标拖动图标技术
Feb 07 Javascript
jQuery Ajax使用 全解析
Dec 15 Javascript
Bootstrap源码解读网格系统(3)
Dec 22 Javascript
jQuery页面弹出框实现文件上传
Feb 09 Javascript
Angular4自制一个市县二级联动组件示例
Nov 21 Javascript
vue.js中引入vuex储存接口数据及调用的详细流程
Dec 14 Javascript
简易Vue评论框架的实现(父组件的实现)
Jan 08 Javascript
vue 中filter的多种用法
Apr 26 Javascript
微信小程序点击保存图片到本机功能
Dec 13 Javascript
vue-cli设置css不生效的解决方法
Feb 07 Javascript
Nuxt页面级缓存的实现
Mar 09 Javascript
微信分享invalid signature签名错误踩过的坑
Apr 11 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
Protoss兵种介绍
2020/03/14 星际争霸
destoon实现底部添加你是第几位访问者的方法
2014/07/15 PHP
PHP面向对象之领域模型+数据映射器实例(分析)
2017/06/21 PHP
php实现微信公众平台发红包功能
2018/06/14 PHP
详解PHP 二维数组排序保持键名不变
2019/03/06 PHP
PHP面向对象程序设计重载(overloading)操作详解
2019/06/13 PHP
node爬取微博的数据的简单封装库nodeweibo使用指南
2015/01/02 Javascript
flash+jQuery实现可关闭及重复播放的压顶广告
2015/04/15 Javascript
JS实现弹性漂浮效果的广告代码
2015/09/02 Javascript
AngularJS ng-bind 指令简单实现
2016/07/30 Javascript
使用JQuery中的trim()方法去掉前后空格
2016/09/16 Javascript
jQuery插件HighCharts绘制2D圆环图效果示例【附demo源码下载】
2017/03/09 Javascript
jQuery模拟窗口抖动效果
2017/03/15 Javascript
微信小程序实战之登录页面制作(5)
2020/03/30 Javascript
Node.js静态服务器的实现方法
2018/02/28 Javascript
js中实例与对象的区别讲解
2019/01/21 Javascript
使用Vue开发自己的Chrome扩展程序过程详解
2019/06/21 Javascript
[05:41]2014DOTA2西雅图国际邀请赛 小组赛7月10日TOPPLAY
2014/07/10 DOTA
[02:49:21]2019完美盛典全程录像
2019/12/08 DOTA
用Python制作在地图上模拟瘟疫扩散的Gif图
2015/03/31 Python
Python pickle模块用法实例
2015/04/14 Python
python实现Flappy Bird源码
2018/12/24 Python
Python中整数的缓存机制讲解
2019/02/16 Python
Python破解BiliBili滑块验证码的思路详解(完美避开人机识别)
2020/02/17 Python
Python爬虫爬取、解析数据操作示例
2020/03/27 Python
Python pexpect模块及shell脚本except原理解析
2020/08/03 Python
用python实现前向分词最大匹配算法的示例代码
2020/08/06 Python
纯css3制作网站后台管理面板
2014/12/30 HTML / CSS
html5 canvas手势解锁源码分享
2020/01/07 HTML / CSS
小学生安全保证书
2014/02/01 职场文书
青春奉献演讲稿
2014/05/08 职场文书
安全承诺书格式
2014/05/21 职场文书
村主任“四风”问题个人对照检查材料思想汇报
2014/10/02 职场文书
副检察长四风问题对照检查材料思想汇报
2014/10/07 职场文书
Nginx 过滤静态资源文件的访问日志的实现
2021/03/31 Servers
使用CSS设置滚动条样式
2022/01/18 HTML / CSS