-
JavaScript作用域和预解析
作用域
概述
- JavaScript作用域:
- 官方解释:一段程序代码中所用到的名字并不总是有效和可用的,限定这个名字的可用性的代码范围,就是这个名字的作用域
- 就是这段代码或变量在某个范围内的作用和效果
- 目的:提高程序逻辑的局部性,增强程序的可靠性,减少名字冲突。
作用域分类
全局作用域
整个script标签,或是一个单独的js文件
局部作用域
(函数作用域)在函数内部就是局部作用域这个代码的名字只在函数内部起效果和作用
ES6新增块级作用域:{} 包含的区域
变量作用域(根据作用域不同)
全局变量
在全局作用域下的变量,在任何位置都可使用
注:在函数内部,没有声明直接赋值的变量也属于全局变量
局部变量
在局部作用域下的变量,在函数内部的变量
注:函数的形参也可以看作局部变量
从执行效率来看全局变量和局部变量
全局变量只有在浏览器关闭时才会销毁,比较占内存
局部变量程序执行完毕就会销毁,比较节约内存资源
作用域链
概述
- 只要是代码,就至少有一个作用域
- 写在函数内部的局部作用域
- 如果函数中还有函数,那么在这个作用域中就又可以诞生一个作用域
- 内部函数可以访问外部函数的变量机制
- 用链式查找决定哪些数据能被内部函数访问,就称作作用域链(就近原则)
预解析
概述
- JavaScript代码是由浏览器中的JavaScript解析器来执行的。
- JavaScript解析器在运行JavaScript代码的时候分为两步:
预解析
和代码执行
。
预解析
- js引擎会把js里
所有的var
还有function
提升到当前作用域
的最前面
分类
- 变量预解析(变量提升)
- 把所有的变量声明提升到当前的作用域最前面,
不提升赋值操作
- 把所有的变量声明提升到当前的作用域最前面,
- 函数预解析(函数提升)
- 把所有的函数声明提升到当前作用域的最前面,
不调用函数
- 把所有的函数声明提升到当前作用域的最前面,
示例
变量提升
console.log(num);//undefined var num=10; // 相当于 var num; console.log(num); num=10;
函数提升
fun(); //报错 // 函数表达式定义函数 var fun = function () { console.log(12) } // 相当于执行以下代码 var fun; fun(); fun = function () { console.log(12) }
例题
var num =10 ; fun(); function fun () { console.log (num); var num = 20; } //相当于执行 var num ; function fun () { var num ; console.log(num); { num = 20 ; } } num = 10 ; fun() ;
函数默认提升优先级较高,相对于变量