JS中关于事件处理函数名后面是否带括号的问题


Posted in Javascript onNovember 16, 2016

今天总结一个关于事件处理程序的小细节。首先回顾一下事件处理的一些概念。

JS中的事件处理(事件绑定)就是让某种或某些事件触发某些活动。有两种常见的形式,分别是DOM Level 0 和DOM Level 2。这两种方式最大的区别就在于DOM 0级事件处理只能用于事件冒泡,而DOM 2级事件处理却可以通过设置第三个参数来分别支持事件冒泡和事件捕获。

DOM 0级事件处理一般是直接把一个函数分配给一个事件处理程序,既可以在元素中直接分配一个事件处理程序,如方式一所示;也可以在脚本中把函数分配给事件处理程序,如方式二所示。

<!--方式一-->
<div onclick="fun1();fun2('world!');"></div>
<!--方式二-->
<div id="a">点我</div>
<script>
var a=document.getElementById("a");
a.onclick=fun1; //方式二 
function fun1(){
alert("hello!");
}
function fun2(cc){
alert(cc);
}
</script>

这两种方式的区别在上述示例中也显示了,第一种方式可以同时绑定多个处理函数,但要注意必须是全局函数,否则会抛出Reference错误。第二种方式只能一次绑定一个处理函数,否则新的函数会覆盖旧的函数。

DOM 2级事件处理不会直接绑定处理函数,而是将函数添加为一个事件监听器如下,他也可以绑定多个处理函数,不会产生覆盖。但这种方式存在浏览器兼容的问题,IE下必须用attachEvent方法代替。

a.addEventListener("click",fun1,false); //事件冒泡
a.addEventListener("click",anotherFun,false); //不会覆盖上一事件,均被执行

简单回顾到这里,言归正传,不知道在回顾的过程中大家有没有注意到一个令人困惑的小细节,就是引用函数的时候,函数名称后面有的时候加括号,有的时候不加括号。这到底对程序的运行有怎样的影响呢?我经过查阅资料按照自己的理解小小的总结如下。

首先是加括号的,你可能经常在程序里面这样写“fun1();”,没错,函数名后边加括号表示立即执行该函数,如果函数内存在返回值则得到该值。这样用的多了,你可能就习惯在所有调用函数的地方这样写,比如之前说的事件处理函数。但是,如果你这样做了那就可能造成一些失控的状况。比如说,你明明只是想在点击某一元素的时候才执行函数,却发现这个函数在一开始就被执行了。你可以发现,上面举例时所用的DOM0方式二和DOM2级事件处理函数都没有在函数名后面加括号,原因就在于避免这种状况发生。如果你加了括号,这个函数fun1就会被立即触发执行。

那为什么DOM0方式一中却有括号呢?那是因为标签的事件属性里引号之间会被当做js语句直接执行,加了括号才能保证调用并执行函数。但是由于是用元素标签这种方式绑定的事件,执行的时机就被控制在了点击该标签时触发。

如果没有函数名又想立即执行呢?也就是立即执行匿名函数表达式,这种模式很常见,来观察一下它的屁股后面是不是也跟着个立即执行小括号呢?注意,这种IIFE形式中包裹着整个函数体的小括号会限制作用域。具体对IIFE感兴趣的童鞋可以去查阅相关资料,这里不作赘述。

(function(){
//do something...
})();

现在再来分析不加括号的,前面我们提到了不加括号可以避免失控。是因为只将函数名传递给事件,相当于将函数指针(也就是这个函数的入口地址)传给元素事件。这样做的好处就在于可以在需要的时候找到函数并执行。打个小比喻来说,你和你的朋友会面,加了小括号时你的朋友就立即出现在你面前,他才不管你当时是不是在忙,有种不请自来的不快感;而不加括号相当于你的朋友告诉了你他家在哪,当你需要他的时候就来找他,这可真是位贴心的朋友啦。所以,大多数事件绑定都仅仅只是传递给事件一个函数指针也就是函数名。

这时又有一个问题,之前说明的都是无参函数,如果是像代码示例中的fun2这种有参函数怎么办呢?难道只能用DOM0的方式一那种方法么?当然是否定的,尽量不要使用DOM0方式一那种形式,不符合结构与行为分离的原则。一般这种情况下就是使用匿名函数解决了,如下代码所示。如果大家有什么好的建议也可以留言分享一下~

//DOM Level 0
a.onclick=function(){
fun2("world!");
};
//DOM Level 2
a.addEventListener("click",function(){fun2("world!");},false);

以上就是我的总结,如有错误还要请大家多多指正,谢谢!感谢一起学习的小伙伴陈童鞋,正是因为他提的问题才让我注意到了这个经常被忽略的细节。

以上所述是小编给大家介绍的JS中关于事件处理函数名后面是否带括号的问题,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
Prototype 工具函数 学习
Jul 23 Javascript
JQuery操作Select的Options的Bug(IE8兼容性视图模式)
Apr 21 Javascript
js实现网页抽奖实例
Aug 05 Javascript
JS排序方法(sort,bubble,select,insert)代码汇总
Jan 30 Javascript
AngularJS基础 ng-options 指令详解
Aug 02 Javascript
JavaScript实现图像模糊化的方法实例
Jan 15 Javascript
jQuery基本选择器和层次选择器学习使用
Feb 27 Javascript
基于JS代码实现简单易用的倒计时 x 天 x 时 x 分 x 秒效果
Jul 13 Javascript
详解如何让InstantClick兼容MathJax、百度统计等
Sep 12 Javascript
Vue起步(无cli)的啊教程详解
Apr 11 Javascript
JavaScript内置对象math,global功能与用法实例分析
Jun 10 Javascript
详解Vue 单文件组件的三种写法
Feb 19 Javascript
微信小程序 时间格式化(util.formatTime(new Date))详解
Nov 16 #Javascript
jQuery实现的购物车物品数量加减功能代码
Nov 16 #Javascript
使用JavaScript获取URL中的参数(两种方法)
Nov 16 #Javascript
微信小程序 保留小数(toFixed)详细介绍
Nov 16 #Javascript
微信小程序 获取相册照片实例详解
Nov 16 #Javascript
js canvas仿支付宝芝麻信用分仪表盘
Nov 16 #Javascript
Javascript使用SWFUpload进行多文件上传
Nov 16 #Javascript
You might like
PHP二维数组排序的3种方法和自定义函数分享
2014/04/09 PHP
PHPCMS手机站伪静态设置详细教程
2017/02/06 PHP
PHP如何实现阿里云短信sdk灵活应用在项目中的方法
2019/06/14 PHP
javascript检查日期格式的函数[比较全]
2008/10/17 Javascript
将CKfinder整合进CKEditor3.0的新方法
2010/01/10 Javascript
用js实现的自定义的对话框的实现代码
2010/03/21 Javascript
深入理解JavaScript系列(44):设计模式之桥接模式详解
2015/03/04 Javascript
JS实现向表格中动态添加行的方法
2015/03/30 Javascript
JavaScript使用cookie记录临时访客信息的方法
2015/04/07 Javascript
测试IE浏览器对JavaScript的AngularJS的兼容性
2015/06/19 Javascript
包含中国城市的javascript对象实例
2015/08/03 Javascript
jquery.cookie.js的介绍与使用方法
2017/02/09 Javascript
AngularJS表单提交实例详解
2017/02/18 Javascript
JS正则表达式验证密码格式的集中情况总结
2017/02/23 Javascript
vuejs2.0运用原生js实现简单的拖拽元素功能示例
2017/02/24 Javascript
js eval函数使用,js对象和字符串互转实例
2017/03/06 Javascript
Angular 4.x中表单Reactive Forms详解
2017/04/25 Javascript
详解nodejs 配置文件处理方案
2019/01/02 NodeJs
vue登录以及权限验证相关的实现
2019/10/25 Javascript
vue prop属性传值与传引用示例
2019/11/13 Javascript
js判断一个对象是数组(函数)的方法实例
2019/12/19 Javascript
django自带的server 让外网主机访问方法
2018/05/14 Python
Python之用户输入的实例
2018/06/22 Python
Python使用pyodbc访问数据库操作方法详解
2018/07/05 Python
基于python历史天气采集的分析
2019/02/14 Python
详解Django3中直接添加Websockets方式
2020/02/12 Python
python 获取计算机的网卡信息
2021/02/18 Python
Zavvi荷兰:英国大型音像制品和图书游戏零售商
2018/03/22 全球购物
Etam俄罗斯:法国女士内衣和家居服网上商店
2019/10/30 全球购物
师范院校学生自荐信范文
2013/12/27 职场文书
财务会计人员求职的自我评价
2014/01/13 职场文书
放弃继承权公证书
2015/01/23 职场文书
2015年环境监察工作总结
2015/07/23 职场文书
2015年圣诞节寄语
2015/08/17 职场文书
党风廉政教育心得体会2016
2016/01/22 职场文书
LyScript实现绕过反调试保护的示例详解
2022/08/14 Python