一.var
var声明具有变量提升的机制,其意思就是在解析代码时,会先读取当前作用域中的所有var。例:
console.log(x) //此处打印undefined,var会使得变量提前被解析,但也只是解析var x而已,知道有这个变量x,但不知道是否被赋值,赋值是多少。
var x = 10
let有严格的解析机制,只有先声明,才可使用。
其优点如下:
- 没定义的变量不能提前使用
- 同一作用域不可let同一变量
- let不仅将函数作为一个作用域,if、for中都可作为一个单独的作用域
console.log(x) //此处报错
let x = 10
// var作用域
console.log(a) //undefined
if(false){
var a = 10 //此时a为全局变量,所以不会报错
}
console.log(a) //undefined
for(var i = 0;i<10;i++){}
console.log(i) //undefined
//let作用域
console.log(a) //报错,此处if内自成一个作用域
if(false){
let a = 10
}
console.log(a) //报错,此处if内自成一个作用域
for(let i = 0;i<10;i++){}
console.log(i) //报错,此处for内自成一个作用域
二.基于ES5—var、function
1.定义阶段(预解析)
找到当前作用域中的var定义的变量,只会读取变量名,不会赋值;且定义多个相同变量名的var时,根据实际代码确定,遵守先解析再按顺序执行代码的原则。
找到当前作用域中的function定义的函数,此时的函数会被看成一个整体,不会执行
2.执行阶段
从头开始,往下执行代码
console.log(x) //定义阶段,若var和function重名,以function为主,此处打印函数体;若function与function重名,后者覆盖前者
var x = 10
function x(){
//函数
}
代码1:
10 var x = 5
11 a()
12 function a(){
13 alert(x)
14 var x = 10
15 }
16 alert(x)
/*分析过程
*1.定义阶段
* 第10行:var x
* 第12-15行:function a(){...} ------产生新作用域----->1.定义阶段
* 第14行:var x
* 2.执行阶段
* 第13行:undefined
* 2.执行阶段(执行时,都是从自己所在的作用域寻找)
* 第11行:执行a()
* 第16行:打印5
*/
代码2:
a()
function a(){
alert(x) //undefined
var x = 10
}
alert(x) //在当前作用域无x,报错
代码3:
alert(a) //弹出40,var与function重名,以function为准;function与function重名,后者覆盖前者
var a = 10
alert(a) //弹出10
function a(){
alert(20)
}
alert(a) //弹出10
var a =30
alert(a) //弹出30
function a(){
alert(40)
}
alert(a) //弹出30
三、break 和continue
在for循环体中,可以使用break直接结束循环;continue结束当前这次的循环体,进入下级循环。