深入理解 JS 中的变量提升

1、JS 的预解析机制

讲变量提升之前,我们先来了解一下 JS 的预解析机制。

JS 的解析和执行
JS 的解析过程分为两个阶段:预编译期(预处理,预解析,预编译)和执行期。

简单来说,所谓的 预解析 就是:在当前作用域内(请注意,当前作用域有可能是全局作用域,也有可能是当前函数的局部作用域),JavaScript 在执行代码之前,浏览器会默认地首先把所有带 var 和 function 声明的变量进行提前的声明或者定义。

var声明的变量和function声明的函数预解析是有去别的,var 声明的变量预解析时只是提前的声明,function 声明的函数在预解析的时候会提前声明并且会同时定义。它们的区别在于声明的同时是否会同时进行定义。

2、变量提升

ES6 之前我们都使用 var 来声明一个变量,提升简单来说就是把我们写的代码类似于 var a = 12;,会首先把 a 的声明在当前作用域的顶端去执行,到我们代码所在位置来赋值。

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

// 它的实际执行顺序如下
var a;
console.log(a);
a = 12;

下面看一道经典面试题

console.log(v1);
var v1 = 100;
function foo() {
    console.log(v1);
    var v1 = 200;
    console.log(v1);
}
foo();
console.log(v1);

结果是

//undefined
//undefined
//200
//100

是不是有点懵,这里我们需要对一些基础知识做些讲解。
在顶级区域内声明的变量为 window 级别的变量,如上面代码第一个 v1 可以理解为 window.v1 = 100

上面代码的解析过程为

var v1;
console.log(v1);
v1 = 100;// window.v1 = 100;
function foo() {
	var v1;
    console.log(v1);
    v1 = 200;
    console.log(v1);
}
foo();
console.log(v1); // console.log(window.v1);
// 再来看执行结果是不是就很清晰了,这里要特别区分全局作用域和局部作用
//undefined
//undefined
//200
//100
3、函数提升

JavaScript 中不仅仅有普通的变量的提升,也有函数的变量提升。具名函数的声明有两种。
1、函数式声明 2、函数字面量声明

// 函数式声明
function foo(){
	console.log(1);
}

// 函数字面量声明
var foo = function(){
	console.log(w);
}

函数字面量式的声明合变量提升的结果是一样的,函数只是一个具体的值;


console.log(foo);
function foo () {
  console.log(1);
}
//打印结果:
// ƒ foo () {
//  console.log(1);
// }

执行顺序相当于:

function foo () {
  console.log(1);
}
console.log(foo);

函数优先
在提升过程中,函数优先提升,其次才是变量提升。只有函数(function a(){ })会被提升,函数表达式会被忽略(var a = function(){ }),相同的函数声明,后面的将会覆盖前面的。

foo(); // 1
var foo;
function foo(){
  console.log(1);
}
foo = function(){
  console.log(2);
}

可以将其理解为

function foo(){
  console.log(1);
}
foo(); // 1
foo = function(){
  console.log(2);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值