#关于父子级作用域的问题:
let i=5;
console.log(i);
{
console.log(i);//形成新的作用域。
}
//输出:两个5,
let i=5;
console.log(i);//5
{
let i=7;
console.log(i);//7
}
变量绑定
④变量绑定:如果区块中存在let 和const命令,则这个区域对这些命令声明的变量是从区块一开始就有的,
一开始就形成封闭作用域
/*******************变量绑定**************/
let i=5;
console.log(i);//5
{
console.log(i);//Uncaught ReferenceError: Cannot access 'i' before initialization
let i=4;
}
/*************变量不允许重复声明*********/
let i=5;
{
//let i=100;
var i=4;
console.log(i);
}//Uncaught SyntaxError: Identifier 'i' has already been declared
var不会形成块级作用域,一次不会在{}中形成自己的作用域,因此就会相当于下面这样
let i=5;
var i=4;
因此会报错,
如果这样:
let i=5;
{
let i=100;
console.log(i);
}
//或
var i=5;
{
let i=100;
console.log(i);
}
//就不会报错了。
总结:
①对于变量,如果父子级作用域都有声明,则值按照自己各自作用域的。
②若仅在父级作用域中存在,则子作用域中的值同父级的。互不干扰
同样的,对于for循环,for循环括号里的设置循环变量的部分是一个父级作用域,
for执行的语句的作用域是一个子级作用域
③let 没有变量提升,var存在变量提升,但是只会提升变量的声明,而不会提升赋值等。会输出undefined
④变量绑定:如果区块中存在let 和const命令,则这个区域对这些命令声明的变量是从区块一开始就有的,
一开始就形成封闭作用域
⑤如果用var声明则不会形成块级作用域,因此如果外部有同样的声明,则被视为变量的重复声明。
关于变量的重复声明,有let和const 不允许,而var:后声明者有效,
⑥尽量避免在块级作用域内声明函数,行为差异较大
⑦var 如果是全局的,那么它就是顶层对象的属性,
而let const命令的全局变量不属于顶层对象的属性