初探内联方式的 onload="doSomething()"为何要加"()"?而js代码的 onload="doSomething" 和 addEventListener 为何不加"()"?
- 问题引入:在看《Jquery基础教程》第四版的时,P34页有这样一段话
引用函数与调用函数
这里在将函数指定为处理程序时,省略了后面的圆括号,只使用了函数名。如果带着圆括号,函数会被立即调用;没有圆括号,函数名就只是函数的标识符或函数的引用,可以用于在将来再调用函数。
这引发了我对于绑定事件方式的思考。我们都知道为元素绑定事件处理程序的时,内联方式要这样写 <body onload="doSomething();">...</body> ,或者javascript代码要这样写
window.onload=doSomething;//或下一行的方式
window.addEventListener('load',doSomething,false);
function doSomething(){
...
}
我们一直都是这样用,但是有没有思考过为什么内联方式的 onload="doSomething()" 要加"()"?我给它不加可以吗?,而js代码的 onload 和 addEventListener 为什么不加"()",我给它加上可以吗?
- 问题思考:如上面书里所说加"()"是调用函数,js代码执行到那一行时函数会被立即调用并执行。不加"()"是引用函数, window.onload 属性只是指向 doSomething 函数体(为什么说是指向而不是将简单的函数体赋值给onload属性待会验证),待将来触发了 onload事件,doSomething才会被加到任务队列等待主函数将它执行。
- 问题验证:
1.标准内联方式,控制台会如约输出"test"。
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body onload="doSomething()">
<script type="text/javascript">
function doSomething(){
console.log('test');
}
</script>
</body>
</html>
2.内联方式不加"()"
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body onload="doSomething">
<script type="text/javascript">
function doSomething(){
console.log('test');
}
</script>
</body>
</html>
结果控制台不输出也没提示出错,来打断点看看程序到底发生了什么,给主要代码每行都打上断点
然后重新运行程序,程序到第6行,暂停。
点击继续执行,程序并没有执行第9行的代码而是运行直接完毕。然后再看下 document.body.onload 属性输出是
所以这就意味着当 onload 事件触发时,去执行 function onload ,该函数内容是 doSomething 啊并不是 doSomething() ,所以 onload 事件触发后不会执行 doSomething 函数只是触发后进入 function onload 就结束了。
3.标准js绑定事件方式, window.onload 和 addEventListener 方式一样,这里用前者举例,也会如约输出"test"
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
window.onload=doSomething;
function doSomething(){
console.log('test');
}
</script>
</body>
</html>
4. js代码换成 doSomething() ,仍然完美输出"test"且没报错,来分析一下
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<script type="text/javascript">
window.onload=doSomething();
function doSomething(){
console.log('test');
}
</script>
</body>
</html>
第8行断点,因为还没执行所以 window.onload=null ,这没有什么疑问, window 对象本身就给这些属性赋值为 null 。继续,
.
来到了第10行断点,准备执行 console ,这时在看 window.onload 怎么还是 null ?莫慌继续看,
经过第10行断点,如约输出"test"没问题,查看 window.onload 还是 null ,直到运行完函数,最后查看 window.onload 依旧是 null ,这个时候会产生疑问是不是由于 doSomething 没有返回明显的值 window.onload 最后才会是null。测试一番
确实是这样的(注:测试过 return 1;return "str"; 都不行,只能 return 对象类型)。
这一系列测试足以说明以下代码完成的功能
window.onload=doSomething();
function doSomething(){
console.log('test');
}
其实就是调用函数并执行然后返回值赋值变量,和注册事件并没啥关系。
- 最后说说前面留的这个问题:window.onload属性只是指向doSomething函数体(为什么说是指向而不是将简单的函数体赋值给onload属性):
给 window.onclick 添加属性 b=1 , window.onchange.b 输出也是1,足以说明确实是指向而不是赋值
初探内联方式的 onload="doSomething()"为何要加"()"?而js代码的 onload="doSomething" 和 addEventListener 为何不加"()"?的更多相关文章
- C++ inline(内联什么时候使用)
(1)什么是内联函数?内联函数是指那些定义在类体内的成员函数,即该函数的函数体放在类体内. (2)为什么要引入内联函数?当然,引入内联函数的主要目的是:解决程序中函数调用的效率问题.另外,前面我们讲到 ...
- C++内联函数与宏定义
用内联取代宏: 1.内联可调试: 2.可进行类型安全检查或自动类型转换: 3.可访问成员变量. 另外,定义在类声明中的成员函数自动转化为内联函数. 文章(一) 内联函数与宏定义 在C中,常用预处理语句 ...
- C++内联函数、函数模板之于头文件
一.基本说明 C++标准中提到,一个编译单元是指一个.cpp文件以及它所include的所有.h文件,.h文件里的代码将会被扩展到包含它的.cpp文件里,然后编译器编译该.cpp文件为一个.obj文件 ...
- C++中的内联函数和C中的宏定义的区别
在C++中内联函数: 内联函数即是在函数的声明和和定义前面加上“inline”关键字,内联函数和常规函数一样,都是按照值来传递参数的,如果参数为表达式,如4.5+7.5,则函数将传递表达式的值(这里为 ...
- CSS 的三种样式 内联 内部 外部
CSS:层叠样式表的缩写 就是 Cascading Style Sheets Cascading Style Sheets : 层叠样式表 优先级问题 :遵守就近原则 内联> 内部>外部 ...
- spring boot 与 thymeleaf (3): 设置属性、条件、遍历、局部变量、优先级、内联语法
前面记录了 thymeleaf 基本表达式, 这里继续看一下其他功能. 一. 设置属性值 这里的controller, html框架 还是沿用上一篇的部分. html: <div class=& ...
- C/C++之宏、内联函数和普通函数的区别
内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算 ...
- c++ 内联函数 (讲解的TM真好)
1. 内联函数 在C++中我们通常定义以下函数来求两个整数的最大值: 复制代码 代码如下: int max(int a, int b) { return a > b ? a : b; } 为 ...
- __inline定义的内联函数和宏的区别
转自:http://blog.csdn.net/lw370481/article/details/7311668 函数与宏 #define TABLE_COMP(x) ((x)>0?(x):0) ...
随机推荐
- 【JavaScript】HTML5存储方案
1.Web SQL 2.IndexedDB 3.Local Storage 4.Session Storage 5.Cookies 6.Application Cache
- 【windows socket+TCPserverclient】
Windows Socket+TCPserverclient Winsock是 Windows下套接字标准. Socket套接字基于计算机网络,提供同一系统上不同进程或由局 ...
- 终端I/O之特殊输入字符
POSIX.1定义了11个在输入时作特殊处理的字符.实现定义了另外一些特殊字符.表18-6摘要列出了这些特殊字符. 表18-6 终端特殊输入字符 在POSIX.1的11个特殊字符中,可将其中9个更改为 ...
- IDEA加密(转)
1. 简介 IDEA是International Data Encryption Algorithm 的缩写,是1990年由瑞士联邦技术学院来学嘉X.J.Lai 和Massey提出的建议标准算法称作P ...
- RHEL 7 命令行注册和激活订阅服务
导读 前一阵子,红帽推出了开发者免费使用订阅功能,只要注册成为红帽开发者就可以免费使用包括 RHEL7 在内的开发套件. 今天我们就来看一看怎么使用命令行来快速注册和激活订阅服务,以后就可以方便地 ...
- uva 12096 The SetStack Computer
点击打开链接uva 12096 思路: STL模拟 分析: 1 题目给定5种操作,每次输出栈顶集合的元素的个数 2 利用stack和set来模拟,set保存集合的元素.遇到push的时候直接在stac ...
- google gflags使用.
code.google.com 被墙的好开心... gflags很简单. 编译使用都很简单. (不像omaha这种丧心病狂的编译依赖). cmake 生成一下. 一路顺风顺水. 值得注意的是: 默认 ...
- PHP.12-PHP-设计文件上传类
设计文件上传类 [PHP参数详解]{文件上传} ********************** *#构造方法编写 ********************** 此种传参方法规定必须用户必须按响应位置输入 ...
- iOS runtime 运行时( 三 )
上一篇 聊的是: 在不知道一个对象有什么属性的情况下, 获取对象的所有属性,然后可以改变属性的值, 今天我们谈谈 怎么通过Category(类别)+runtime 给一个类 添加一个新的属性,一般情况 ...
- 1.7.5 Faceting
1. 分面(Faceting) 分面就是将搜索结果基于索引中的terms按类整理.搜索结果带有索引的term,没有term都带有该term匹配的文档数.分面使用户更容易探究搜索结果,缩小查询结果范围以 ...