一、作用域
1、js的作用域:代码名字也就是变量,在某个范围内起作用或者效果,可以减少重复命名冲突
js作用域(es8):全局作用域:整个scipt标签或者一个单独的js文件 如:
var num=10
和 局部作用域:在函数内部就是局部作用域,这个代码的名字只在函数内部起效果和作用
function f(){
//局部作用域
}
现阶段js没有块级作用域,也是在es6上新增了块级作用域{}
变量作用域:全局变量和局部变量:函数的形参可以看作局部变量
全局变量只有浏览器关闭的时候才会销毁,比较占内存。
局部变量当程序执行完毕就会销毁,比较节省资源
注意:如果在函数内部没有声明而是直接赋值的变量也属于全局变量
function f(){
//局部作用域
var num1=10
num2=20//全局变量
}
console.log(num2)
2、作用域链
根据内部函数可以访问外部函数变量的这种机制,用链式查找决定哪些数据能被内部函数访问,就称为作用域链。就近原则,查的时候往上看。
二、预解析
1、js代码是通过浏览器中的解析器来执行,运行代码包括两步:预解析和代码执行
预解析:js引擎会把js里面所有的var还有function提升到当前作用域的最前面
代码执行:按照代码写的顺序,从上到下执行
预解析分为变量预解析(变量提升)和函数预解析(函数提升)
变量提升:就是把所有变量声明提升到当前的作用域最前面 ,不提升赋值操作
如:console.log(num)
var num=10
就相当于
var num
console.log(num)
num=10
函数提升:把所有的函数声明提升到当前作用域的最前面
案例:
f1()
console.log(c)
console.log(b)
console.log(a)
function f1(){
var a=b=c=9;//相当于var a=9; b=9; c=9 ;这里b和c没有var声明,是赋值,是全局变量
//集体声明是这样的 var a=9,b=9,c=9,用的是逗号
console.log(a)
console.log(b)
console.log(c)
}
相当于代码
function f1(){
var a;
a=b=c=9;
console.log(a)
console.log(b)
console.log(c)
}
f1()
console.log(c) //c=9
console.log(b) //b=9
console.log(a) //因为a是局部变量,不能调用,所以会报错。