js中关于事件处理函数名后面是否带括号的问题
今天总结一个关于事件处理程序的小细节。首先回顾一下事件处理的一些概念。
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中关于事件处理函数名后面是否带括号的问题的更多相关文章
- JS:JS中常见的 “函数名 is not a function” 错误
js中常见的错误,例如Uncaught TypeError: x is not a function 其原因除了函数本身有错之外,还有一种很奇怪的情况:函数本身没有错,但是运行时就是不能正常运行.这种 ...
- js中绑定事件处理函数,使用event以及传递额外数据
IE8中使用attachEvent绑定事件处理函数时,不能直接向event 对象添加数据属性.可以用属性复制的方法,包装新的event对象. 1. 属性复制var ObjectExtend = fun ...
- js中的匿名函数和匿名自执行函数
1.匿名函数的常见场景 js中的匿名函数是一种很常见的函数类型,比较常见的场景: <input type="button" value="点击" id ...
- JS中关于把函数作为另一函数的参数的几点小总结
//JS中关于把函数作为函数的参数来传递的问题的小总结//第一,最简单的形式无参函数,直接形式函数的函数名放到括号中,再在执行部分这个函数即可.//当然调用时要穿另一个真正的定义好的函数/*funct ...
- js中的回调函数的理解和使用方法
js中的回调函数的理解和使用方法 一. 回调函数的作用 js代码会至上而下一条线执行下去,但是有时候我们需要等到一个操作结束之后再进行下一个操作,这时候就需要用到回调函数. 二. 回调函数的解释 因为 ...
- underscore.js中的节流函数debounce及trottle
函数节流 throttle and debounce的相关总结及想法 一开始函数节流的使用场景是:放止一个按钮多次点击多次触发一个功能函数,所以做了一个clearTimeout setTimeou ...
- js中如何在一个函数里面执行另一个函数
1.js中如何在函数a里面执行函数b function a(参数c){ b(); } function b(参数c){ } 方法2: <script type="text/javasc ...
- JavaScript -- 时光流逝(七):js中的全局函数
JavaScript -- 知识点回顾篇(七):js中的全局函数 全局函数可用于所有内建的 JavaScript 对象. (1) encodeURI():把字符串编码为 URI. <script ...
- js语法没有任何问题但是就是不走,检查js中命名的变量名,用 service-area错误,改service_area (原)
js语法没有任何问题但是就是不走,检查js中命名的变量名,用 service-area错误,改service_area
随机推荐
- [iOS基础控件 - 6.11.5] 沙盒 & 数据存储
A.沙盒 每个APP都有一个沙盒,是独立存在的 1.Xcode5和Xcode6的模拟器文件目录 a.模拟器路径改版 (1)Xcode5中模拟器路径为:/Users/用户名/Library/Appl ...
- LCA + 二分(倍增)
两个最近的点u和v的最近的公共的祖先称为最近公共祖先(LCA).普通的LCA算法,每算一次LCA的时间复杂度为线性o(n); 这里讲LCA + 二分的方法.首先对于任意的节点v,利用其父节点的信息,可 ...
- CodeForces 707C Pythagorean Triples (数论)
题意:给定一个数n,问你其他两边,能够组成直角三角形. 析:这是一个数论题. 如果 n 是奇数,那么那两边就是 (n*n-1)/2 和 (n*n+1)/2. 如果 n 是偶数,那么那两边就是 (n/2 ...
- DllImport属性详解
API函数是构筑Windows的基石, 是Windows编程的必备利器.每一种Windows应用程序开发工具都提供间接或者直接的方式调用Win32API,C#也不例外.使用Win32API的一个好处就 ...
- 剑指OFFER之反转链表(九度OJ1518)
题目描述: 输入一个链表,反转链表后,输出链表的所有元素.(hint : 请务必使用链表) 输入: 输入可能包含多个测试样例,输入以EOF结束.对于每个测试案例,输入的第一行为一个整数n(0<= ...
- @Override must override a superclass method 问题解决
一.问题的由来 最近接手了了一个合作企业的项目,前期不是我司开发的,上周做了几天的技术对接,客户端界面由我负责对接,从svn检出之后,迫不及待的导入到了本地的myeclipse中,谁知立马就出现了那个 ...
- How Much Work Does it Take to be a Successful Mathematician?
http://mathoverflow.net/questions/9799/how-much-work-does-it-take-to-be-a-successful-mathematician# ...
- 架构师之路(39)---IoC框架
1 IoC理论的背景 我们都知道,在採用面向对象方法设计的软件系统中,它的底层实现都是由N个对象组成的,全部的对象通过彼此的合作,终于实现系统的业务逻辑. 图1:软件系统中耦合的对象 假设 ...
- Codeforces 278C Learning Languages(并查集)
题意抽象出来就是求联通块的个数吧,然后添加最少边使图联通. 注意所有人都不会任何语言的时候,答案是n而不是n-1. #include<algorithm> #include<iost ...
- mapreduce2运行流程