作用域 和 预解析
1.作用域
作用域就是变量在某个范围内起作用,可提高程序的可靠性,主要是为了减少命名冲突
- js的作用域(es6之前):全局作用域和局部作用域
- 全局作用域:整个script标签,或者是单个的js文件
- 局部作用域(函数作用域):在函数内部就是局部作用域,变量只在函数内部起作用
2.变量作用域
全局变量:在全局作用域下的变量;如果在函数内部没有声明直接赋值的变量也属于全局变量
局部变量:在局部作用域下的变量 在函数内部的变量就是局部变量
3.作用域链
在函数内部的变量,如果函数中还有函数,那么内部函数就可以访问外部函数定义的变量
4.预解析
js引擎运行js代码分为两步:预解析和代码执行
- 预解析: js引擎会把js里所有的 var (变量声明) 还有 function(函数) 提升到当前作用域的最前面
- 代码执行: 按照代码的书写顺序从上往下执行
预解析分为 变量预解析(变量提升)和 函数预解析 (函数提升)
- 变量提升:就是把所有的变量声明提升到当前的作用域最前面, 不提升赋值
- 函数提升: 就是把所有的函数声明提升到当前作用域的最前面 , 不调用函数
5. 变量提升 和 声明变量陷阱
- 预解析中的变量提升,只提升声明变量的过程,不提升赋值的过程。如:
var num = 2;
function fn() {
console.log(num);
var num = 3;
console.log(num);
}
fn(); // 结果 :undefined 和 3
相当于
var num; // 只提升声明的步骤
function fn() {
var num; // 只提升变量声明
console.log(num);
num = 3; // 赋值过程
console.log(num);
}
num = 2; // 赋值的过程还是将变量和函数都提升之后,按顺序执行
fn();
- 声明变量陷阱
var a = b = 1;
// 相当于var a = 1; b =1;
// 如果此代码在一个函数中,那么 a 就是函数内部的变量(局部变量),b 没有声明直接赋值就是全局变量
// 集体赋值: 这样 a 和 b 的作用域是一样的
var a = 1, b = 1;