作用域
- 全局作用域和函数作用域出现的问题。
var tmp=new Date();
function f(){
console.log(tmp);
if(false){
var tmp='hello';
}
}
f();
//内层变量可能会覆盖外层变量
var s='hello';
for(var i=0;i<s.length;i++){
console.log(s[i]);
}
console.log(i);
//用来计数的循环变量泄露为全局变量
var关键字
1.var声明作用域
function test (){
var message = "hi";//局部变量
}
test();
consloe.log(message);//报错
多个变量同时声明
var message="hi",
found = false;
age = 29;
2.var 声明提升
function foo(){
console.log(age);
var age = 26;
//相当于
/*var age;
console.log(age);
age = 26;*/
}
foo();//undefined
此外,反复 多次使用var声明同一变量也可以
function foo(){
var age=16;
var age = 26;
var age = 36;
console.log(age);
}
foo();//36
let声明
let 与var最明显的区别是:let声明的范围是块作用域,而var声明的是函数作用域。
if(true){
var name = 'mate';
console.log(name);//mate
let age = 20;
console.log(age);//20
}
console.log(name);//mate
console.log(age);//报错,age没有定义
此外,反复多次使用let声明同一变量是不被允许的。
1.变量提升
let声明的变量不会在作用域中被提升。
function getValue(c){
if(c){
var value='blue';
return value;
}else{
return null;
}
}
function getValue(c){
var value;
if(c){
value='blue';
return value;
}else{
return null;
}
}
2.暂时性死区
var temp=123;
if(true){
temp='abc';
let temp;
}
- 使用let命令声明变量之前,该变量都是不可用的
3.全局声明
let在全局声明的变量不会成为window对象属性
var name = 'mat';
console.log(window.name);//mat
let age = 15;
console.log(window.age);//undefined
3.for循环中的let声明
for(var i=0;i<10;i++){
console.log(i);
}
console.log(i);
for(let i=0;i<10;i++){
console.log(i);
}
console.log(i);
}
在第一关循环中,因为在退出循环时,迭代变量保存的是导致循环退出的:5.在之后执行超时逻辑,所有的 i 都是同一个变量。
for(let i=0;i<5;i++){
setTimeout(()=>console.log(i),0);//0 1 2 3 4
}
js引擎中后台会为每一次迭代循环声明一个新的迭代变量,而每个srtTimeout引用的都是不同的变量实例。
3.const声明
const的行为和、let基本相同,但const在声明变量时必须同时初始化变量,且不能修改变量的值。
//const的作用域也是块作用域
const name = 'mat';
if(true){
const name = 'abc';
const name = "app";//报错
}
console.log(name);//mat