一 a=1
在没有声明变量a的前提下,a=1会隐式地声明一个全局变量
a=1;
console.log(window.a)
//a=1声明全局变量a,打印1
var a;
function fn(){
a=1;
console.log(window.a);
}
fn()
//a=1是给函数fn外var声明的全局变量a赋值,打印1
function fn2(){
var a;
fn3();
function fn3(){
a=1;
console.log(window.a)
}
}
fn2()
//a=1是给函数fn3外var声明的局部变量a赋值,因此打印undefined
含义不明,尽量不要使用
二 var
- 变量提升
a=1
console.log(a);
console.log(window.a)
var a;
//var a会变量提升,自动跑到最前面,因此打印1
//同时函数外声明会自动成为全局变量
{
var a=1;
}
console.log(a);
//var a=1会变量提升,因此打印1
//如果此处仅var a;没有给a赋值,那么会打印undefined
- 函数作用域
function fn(){
var a=1;
}
console.log(a)
//var具有函数作用域,此时a是函数fn的局部变量,因此外部访问不到,故报错
三 let
没有变量提升,必须先声明再使用,不能重复声明,块作用域
{
let a=1;
}
console.log(a);
//a为局部变量,故报错
//let可以很方便的声明局部变量
//没有let之前,由于var有变量提升且var为函数作用域,因此为了使用局部变量,必须用函数在最外层包裹,这样会多暴露一个函数名,为了简化,故有了立即执行函数
{
var a=1;
}
console.log(a);
//打印1
(function(){
var a=1;
}())
console.log(a);
//报错
{
console.log(a);
let a=1;
}
//必须先声明再使用(临时性死区)
{
let a=1;
let a=2;
}
//重复声明,报错
四 const
没有变量提升,必须先声明再使用,不能重复声明,块作用域。
常量,不能重复赋值,且声明的时候必须赋值
{
const a=1;
a=2;
}
//报错
{
const obj={name:'1'};
obj.name='2';
console.log(obj.name);
}
//对象的地址并没有改变,因此打印2
五 总结
- 在没有声明变量a的前提下,a=1会隐式地声明一个全局变量
- var
变量提升,函数作用域 - let
没有变量提升,必须先声明再使用,不能重复声明,块作用域 - const
没有变量提升,必须先声明再使用,不能重复声明,块作用域。常量,不能重复赋值,且声明的时候必须赋值