通过var声明的变量存在变量提升的特性
if(condition){
var value = 1;
}
console.log(value);
// 并不是condition为true时才创建value
// 代码相当于
var value;
if(condition){
value = 1;
}
console.log(value);
// 如果condition为false则是undefined
在for循环中
for(var i=0; i<10; i++){
// ...
}
console.log(i); // 10
循环结束了,依然可以访问i的值
块级作用域存在于:
- 函数内部
- 块中 () 或者 {} 之间的区域
块级声明用于声明在指定块的作用域之外无法访问的变量
let和const的特点:
1. 不会变量提升
if(false){
let value = 1;
}
console.log(value); // error
2. 重复声明报错
let value = 1;
let value = 2; // error
3. 不绑定全局作用域
// var
var value = 1;
console.log(window.value); // 1
// let const
let value = 1;
console.log(window.value); // undefined
let和const的区别
const用于声明常量,其值一旦设定不能再被修改,否则会报错
const声明不允许修改绑定,但允许修改值
const data = {
value: 1
}
// 没问题
data.value = 2;
data.num = 3;
// 报错
data = {}; // error
let和const声明的变量不会被提升到作用域顶部,如果在声明之前访问这些变量,会报错
var value = "global";
// 例子1
(function() {
console.log(value);
let value = 'local';
}());
// 例子2
{
console.log(value);
const value = 'local';
};
两个例子都不会打印 'global',而是报错,就是因为TDZ的缘故
let value = 1;
// 编译为
var value = 1;
if(false){
let value = 1;
}
console.log(value); // error
// 编译为
if(false){
var _value = 1;
}
console.log(value);
// 本质一样 修改变量名,使内外层的变量名称不一样
// const修改值以及重复声明报错,其实是在编译的时候直接给你报错
// 循环的let
var funcs = [];
for(let i=0; i<10; i++){
funcs[i] = function(){
console.log(i);
}
}
funcs[0](); // 0
// 编译为
var funcs = [];
var _loop = function _loop (i) {
funcs[i] = function () {
console.log(i);
}
}
for(var i=0; i<10; i++){
_loop(i);
}
// 如果实现占用_loop变量名,则会编译为_loop2
funcs[0](); // 0