js是解释型语言:编译一行,执行一行。
函数类型
由于执行过程中预编译时,两种类型加载情况不同,所以
声明式函数可先使用,再声明【预编译时加载,此时不会执行,解释执行时,被调用时才执行】
赋值式函数须先声明,再使用【预编译时var func=undefined】
立即执行函数:直接执行,无需调用【预编译时加载,此时不会执行,解释执行时直接执行,无需调用】
- 声明式函数:function func(){};
- 赋值式函数:var func=function(){};
- 立即执行函数:(function(a){}(a)); (function(a){})(a);
对于只用一次的函数,防止执行后浪费内存,以立即执行函数的形式执行后,就会立即删除(无论有没有名字)
主要用于:初始化
立即执行函数会形成一个单独的作用域,我们可以封装一些临时变量或者局部变量,避免污染全局变量
- 经典闭包问题
<ul id="li"> <li>公司简介</li> <li>联系我们</li> <li>营销网络</li> </ul> <script> var list = document.getElementById("li"); var li = list.children; for(var i = 0 ;i<li.length;i++){ li[i].onclick=function(){ alert(i); // 结果总是3.而不是0,1,2。因为 用户一定是在 for 运行完了以后,才点击,此时 i 已经变成 3 了。 } } //解决办法1 for(var i = 0 ;i<li.length;i++){ ( function(j){ li[j].onclick = function(){ alert(j); })(i); //把实参i赋值给形参j } } //解决办法2 ES6 的块级作用域 for(let i = 0 ;i<li.length;i++){ li[i].onclick=function(){ alert(i); // 结果是0,1,2 } } </script>
alert(a);a=1;//a未声明报错
alert(a);var a=1;//输出undefined
# 执行过程
对于js文件和一段段的\<script\>,在每个文件或每段执行前进行该区域内代码的:
* 语法分析
* 是否有语法错误
* 预编译
* 加载声明式函数
* 声明所有var变量为undefined(包括赋值式函数)
var a=1;//预编译时a为undefined
var func = function(){};//预编译时func为undefined
* 解释执行
# 参考
https://www.cnblogs.com/jdWu-d/p/11587805.html
https://www.cnblogs.com/vickylinj/p/12191958.html