let
循环与let之间的联动
1.“变量i是Let声明的,当前的i只在本轮循环有效。所以每一次循环的i其实都是一个新的变量”
var a=[];
for(let i=0;i<10;i++){
a[i]=function(){
console.log(i)
}
}
a[6]()//6
2.“设置循环变量的部分是一个父作用域,循环体内部是一个单独的子作用域”
for(let i=0;i<3;i++){
let i="abc"
console.log(i)//'abc'
}
暂时性死区
“只要块级作用域存在let命令,他所声明的变量就“绑定”这个区域,不再受外部影响”
在变量的死区中无法使用该变量,也就是没有变量提升
var tmp=123
if(true){
//变量tmp死区开始
tmp='abc'//ReferenceError
let tmp;//变量tmp死区结束
}
不允许重复声明
块级作用域
为什么需要块级作用域
1."内层变量可能会覆盖外层变量"
var tmp=new Date()
function f(){
console.log(tmp)
if(false){
var tmp='hello world'
}
}
f()//undefined(内层tmp变量提升覆盖外层变量)
2.“计数的循环变量泄露为全局变量”
var s='hello'
for(var i=0;i<s.length;i++){
console.log(s[i])
}
console.log(i)//5(循环结束后,变量i并没有消失,泄露为了全局变量)
ES6的块级作用域
"let实际上为javascript新增了块级作用域"
"Es6允许块级作用域的任意嵌套"
"外层作用域无法读取内层作用域的变量,内层作用域可以定义外层作用域的同名变量"
块级作用域与函数声明
“考虑到环境导致的行为差异太大,应该避免在块级作用域内声明函数。如果确实需要,应该写成函数表达式的形式”
//(块级作用域下)函数声明
{
let a='secret'
function f(){
return a
}
}
//(块级作用域下)函数表达式
{
let a='secret'
let f=function(){
return a
}
}
const
本质
"变量指向的那个内存地址不得改动"
//foo对象添加一个属性,可以成功
foo.prop=123;
const foo={}
//foo指向另一个对象,就会报错
foo={};//TypeError:"foo" is read-only