se6中的块级作用于let与const
1.var声明声明的变量会进行变量提升Hoisting
function getValue(condition){
if(condition){
var value = "blue"
//其他代码
return value
}else{
//此处可访问value,其值为undefined
return null
}
//此处可访问value,其值为undefined
}
其实,无论condition值是否为true,变量都会被创建,在预编译阶段,上面的代码会改为
function getValue(condition){
var value;
if(condition){
value = "blue"
//其他代码
return value
}else{
//此处可访问value,其值为undefined
return null
}
//此处可访问value,其值为undefined
}
其实是进行了变量的提升,被提升至函数的顶部,初始化操作依旧在 condition条件内
2.块级声明
(1)let 和const是块级作用域,不会进行变量的提升操作。
function getValue(condition){
if(condition){
letvalue = "blue"
//其他代码
return value
}else{
//此处不存在value
return null
}
//此处不存在value
}
(2)禁止重复声明
const和let只在当前代码块内有效,一旦执行到块外会立即被销毁。
var count = 30
let count = 40 // 抛出语法错误
但是在当前作用域内嵌另外一个作用域,可在内嵌的作用域使用let声明同名变量
var count = 40
if(conditon){
let count = 50 //不会抛出错误
}
const声明变量需进行初始化操作:
const max = 30;
const name ; // 语法错误,常量未初始化
max=40 // 抛出语法错误,const声明的变量是常量,不能修改绑定,即不能修改值
但是const声明的对象可修改其对象属性的值:
const person = {
name:"liuhp"
}
person.name = "lal" // 可修改其对象属性的值
person = {name:"nan"} //抛出语法错误
(3)临时死去
if(condition){
console.log(typeof value) //引用错误
let value = "blue"
}
let value = "blue"不会被执行
js引擎遇到const与let声明时,会将声明放到TDZ(Temporal Dead Zone)中,var 会将声明提升至作用域顶部
在声明的作用域外不会报错
console.log(typeof value) // "undefined"
f(condition){
let value = "blue"
}
(3)循环中的块级作用域绑定
var funcs = []
for(var i = 0 ; i< 10 ; i++){
funcs.push(function(){
console.log( i )
})
}
funcs.forEach(function(func){
func() ; //输出10次数字10
})
js一般解决办法
使用立即调用函数表达式(IIFE)
var funcs = []
for(var i = 0 ; i< 10 ; i++){
funcs.push((function(){
return function(){
console.log( i )
}
}(i)))
}
funcs.forEach(function(func){
func() ; //输出0~9
})
es6使用let
var funcs = []
for(let i = 0 ; i< 10 ; i++){ //每次声明会创建一个新的变量i,并将其初始化为i的当前值,使用const不行
funcs.push(function(){
console.log( i )
})
}
funcs.forEach(function(func){
func() ; //输出0~9
})
但是使用const不行,因为i++值需要改变;
但是for遍历对象的key 使用const与let行为是一致的。
var funcs = [],
object = {
a:true,
b:true,
c:true
}
for(const key in object){ //不会产生错误
funcs.push(function(){
console.log( key )
})
}
funcs.forEach(function(item){
item(); //输出a,b,c
})
3.全局作用域绑定
(1)var声明的全局变量会是window对象中的变量
var RegExp = "hello"
console.log(window.RegExp ) //hello,意味着var可能无意中覆盖了一个已经存在的全局属性
(2)使用let和const在全局声明,不会添加全局对象属性
let RegExp = "hello"
console.log(RegExp ) //hello
console.log(window.RegExp === RegExp ) //false
使用let 和 const安全的多