var声明及变量提升机制
function getValue(condition){
if(condition){
var value = "blue";
return value;
} else {
console.log(value);
}
console.log(value);
}
getValue(0)
//undefined
//undefined
在预编译阶段js引擎会将上面函数修改成下面这样
function getValue(condition){
var value
if(condition){
value = "blue";
return value;
} else {
console.log(value);
}
console.log(value);
}
块级声明
function getValue(condition){
if(condition){
let value = "blue";
} else {
//变量value在此处不存在
return null
}
//变量value在此处不存在
}
var count = 30;
let count = 30;
//Uncaught SyntaxError: Identifier 'count' has already been declared
var count = 30;
if(condition){
let count = 10;
//不会抛出错误
}
const maxItems = 30;
const name;
//Uncaught SyntaxError: Missing initializer in const declaration
const maxItems = 5;
maxItems = 6;
//Uncaught TypeError: Assignment to constant variable.
const person = {name: 'binperson'}
//可修改对象属性的值
person.name = 'bin'
//抛出语法错误
person = {
name: 'bin'
}
//Uncaught TypeError: Assignment to constant variable.
临时死区(TDZ)
if(condition){
console.log(typeof value);//引用错误!
let value = "blue";
}
//Uncaught ReferenceError: value is not defined
console.log(typeof value) //"undefined"
if(condition){
let value = "blue";
}
//循环中的块作用域绑定
for(var i = 0; i < 10; i++){
}
console.log(i)//10
for(let j = 0; j < 10; j++){
}
//i在这里不可访问,抛出一个错误
console.log(j);
//Uncaught ReferenceError: j is not defined
var funcs = [];
for (var i=0; i < 10; i++){
funcs.push(function(){
console.log(i);
});
}
funcs.forEach(function(func){
func();//输出10次数字10
});
var funcs = [];
for(var i = 0; i < 10; i++){
funcs.push(function(value){
return function(){
console.log(value);
}
}(i));
}
funcs.forEach(function(func){
func();//输出0,然后1、2,直到9
});
var funcs = []
for(let i = 0; i < 10; i++){
funcs.push(function(){
console.log(i);
})
}
funcs.forEach(function(func){
func();//输出0,然后1、2,直到9
});
var funcs = [],
object = {
a: true,
b: true,
c: true
};
for(let key in object){
funcs.push(function(){
console.log(key);
})
}
funcs.forEach(function(func){
func();//输出a、b、c
})
//如果使用var声明key,则都会输出c
var funcs = []
for(const i = 0; i < 10; i++){
funcs.push(function(){
console.log(i);
})
}
funcs.forEach(function(func){
func();
});
//Uncaught TypeError: Assignment to constant variable.
var funcs = [],
object = {
a: true,
b: true,
c: true
};
for(const key in object){//每次迭代不会修改已有绑定,而是会创建一个新绑定
funcs.push(function(){
console.log(key);
})
}
funcs.forEach(function(func){
func();//输出a、b、c
})
//浏览器中
var RegExp = "Hello!";
console.log(window.RegExp); //"Hello!"
var ncz = "Hi!";
console.log(window.ncz);//"Hi!"
//let或const不能覆盖全局变量,而只能屏蔽它
let RegExp = "Hello!";
console.log(RegExp);//"Hello!"
console.log(window.RegExp); //ƒ RegExp() { [native code] }
console.log(window.RegExp === RegExp)//false
const ncz = "Hi!";
console.log(ncz);//"Hi"
console.log(window.ncz);//"Hi!"
console.log(window.ncz === ncz); //true
console.log("ncz" in window)//false
- 如果希望在全局对象下定义变量,仍然可以使用var。这种情况常见于在浏览器中跨frame或跨window访问代码
块级绑定最佳实践的进化
- 默认使用const,只有确实需要改变变量的时使用let