javascript易踩的坑0x01:var变量声明提升

var变量声明提升

var提升的是变量的“声明”,不是变量的“赋值”。

“提升”指把“声明”提升到各层作用域的顶端执行。

分清楚变量的“声明”、“定义”、“初始化”之间的区别。

Kevin 认为 js中的“声明”=“定义”+初始化为“undefined”
Kevin 认为 js中的定义提升,是let、var都能做到的,就是在js引擎真正解释整份代码文件前,会把let、var定义的变量,预先写入各层作用域的命名空间中。但变量声明提升(定义+初始化为undefined)只有var可以做到。因此会有以下现象:

console.log(a); // 报错,a未定义

console.log(a); // 报错,a未初始化前,不能使用a
let a = 1;

let a;
console.log(a); // undefined

console.log(a); // undefined
var a=1;

第二段代码中,let虽然写在第二行,但还是对第一行造成影响,符合一开始的推论:let对变量a做了定义,但是没有初始化为undefined。

为证实推论,进一步验证其在函数局部作用域中的表现差异

var a = 1;
function fn(){
    console.log(a); // 1
}
fn();

var a = 1;
function fn(){
    console.log(a); // 报错,a未初始化前,不能使用a
    let a = 2;
}
fn();

var a = 1;
function fn(){
    console.log(a); // undefined
    var a = 2;
}
fn();

发现的确,只要在一个局部作用域里的任何位置let或var定义变量,这种定义都会被提升,但只有var提升的同时还做了初始化undefined。

有了上面的推论,下方的实验结果就很好理解了

var a = 1;
console.log(a);     // 1
function fn(){
    console.log(a); // undefined
    var a=2;
    console.log(a); // 2
}
var a = 100;
fn();
console.log(a);     // 100
var a;
console.log(a);     // 100
var a=200;
console.log(a);     // 200
  1. 可以理解为:声明=定义+初始化为undefined
  2. 声明与赋值无关
  3. 变量的定义无论出现在该层作用域的哪一行,都会对整个作用域发生影响(let、var表现一致)
  4. var的变量声明提升,比let多了一个初始化为undefined的过程
  5. 声明提升,但声明连带的赋值不提升(var a=100;),赋值语句原来在哪行发生,还是在哪行发生。
  6. 已经用var声明的变量,再次不赋值地声明(var a;),并不会对其原来的值造成影响;
  7. 已经用var声明的变量,再次用赋值来声明(var a=200;),则可以理解为仅仅是在该行进行一次新的赋值,而没有所谓的重新定义与初始化。

PS:另外同一层作用域,var可以对同一变量名重复多次声明,但let不行。

var 的变量声明如果是在函数内部(在函数内部变量提升),则函数外部仍旧是没有定义这个变量的;但如果var的变量声明是在函数外部的(无论是 for 语句中 还是某个语句块),则是在全局作变量提升的,全局都能访问到这个变量。

{
  var a=1;   
}
console.log(a);   // 1
function abc(){
   var aa = 1;
}
abc();
console.log(aa);  // 报错 aa 未定义。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值