引用函数,调用函数,揭秘

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了引用函数,调用函数,揭秘相关的知识,希望对你有一定的参考价值。

         

  • 问题引入:在看《Jquery基础教程》第四版的时,P34页有这样一段话

引用函数与调用函数

  这里在将函数指定为处理程序时,省略了后面的圆括号,只使用了函数名。如果带着圆括号,函数会被立即调用;没有圆括号,函数名就只是函数的标识符或函数的引用,可以用于在将来再调用函数。

这引发了我对于绑定事件方式的思考。我们都知道为元素绑定事件处理程序的时,内联方式要这样写 <body onload="doSomething();">...</body> ,或者javascript代码要这样写

1 window.onload=doSomething;//或下一行的方式
2 window.addEventListener(‘load‘,doSomething,false);
3 function doSomething(){
4     ...
5  }

我们一直都是这样用,但是有没有思考过为什么内联方式的 onload="doSomething()" 要加"()"?我给它不加可以吗?,而js代码的 onload 和 addEventListener 为什么不加"()",我给它加上可以吗?

  • 问题思考:如上面书里所说加"()"是调用函数,js代码执行到那一行时函数会被立即调用并执行。不加"()"是引用函数, window.onload 属性只是指向 doSomething 函数体(为什么说是指向而不是将简单的函数体赋值给onload属性待会验证),待将来触发了 onload事件,doSomething才会被加到任务队列等待主函数将它执行。
  • 问题验证

     1.标准内联方式,控制台会如约输出"test"。

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4   <title></title>
 5 </head>
 6 <body onload="doSomething()">
 7 <script type="text/javascript">
 8   function doSomething(){
 9     console.log(test);
10   }
11 </script>
12 </body>
13 </html>

     2.内联方式不加"()"

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4   <title></title>
 5 </head>
 6 <body onload="doSomething">
 7 <script type="text/javascript">
 8   function doSomething(){
 9     console.log(test);
10   }
11 </script>
12 </body>
13 </html>

结果控制台不输出也没提示出错,来打断点看看程序到底发生了什么,给主要代码每行都打上断点

技术分享

然后重新运行程序,程序到第6行,暂停。

技术分享

点击继续执行,程序并没有执行第9行的代码而是运行直接完毕。然后再看下 document.body.onload 属性输出是

技术分享

所以这就意味着当 onload 事件触发时,去执行 function onload ,该函数内容是 doSomething 啊并不是 doSomething() ,所以onload事件触发后不会执行something函数只是触发后进入function onload就结束了。

   3.标准js绑定事件方式,window.onload和addEventListener方式一样,这里用前者举例

 

以上是关于引用函数,调用函数,揭秘的主要内容,如果未能解决你的问题,请参考以下文章

函数调用栈(Call Stack)

揭秘PHP匿名函数

深入了解C++ (13) | 走近vtprvtbl,揭秘动态多态

C++中虚函数实现原理揭秘

为啥python的函数没被调用就被执行了?

揭秘 Kotlin 1.6.20 重磅功能 Context Receivers