JavaScript 预编译(变量提升和函数提升的原理)

1.变量提升

console.log(global); // undefined
var global = 'global';
console.log(global); // global
 
function fn () {
  console.log(a); // undefined
  var a = 'aaa';
  console.log(a); // aaa
}
fn();

疑问一:还没有定义a和global,为什么就变成了undefined呢?

2.函数提升

console.log(f1); // function f1() {}   
console.log(f2); // undefined  
function f1() {}
var f2 = function() {}

疑问二:console.log(f1)为什么能够输出还未定义初始化的f1函数呢?

疑问三:类似于疑问一,为什么f2还没定义,就输出undefined呢?

这些疑问的答案,都来自JS的预编译机制:

3.预编译

JS并不会完全按照代码顺序进行解析执行,而是在解析之前进行一次“预编译”。在此过程中,会把:

  1. 定义式的函数优先执行
  2. 所有var变量定义,默认值为undefined

这就解释了上面两段代码输出的原因了,上面的两段代码我们可以用下面的形式理解:

变量提升:

var global;
console.log(global); // undefined
global = 'global';
console.log(global); // global
 
function fn () {
      var a;
  console.log(a); // undefined
  a = 'aaa';
  console.log(a); // aaa
}
fn();

函数提升:

function f1() {}
var f2;
console.log(f1); 
console.log(f2); 
f2 = function() {}

4.容易出错的一点

// 调用函数,返回值1
f();                                 
function f(){
    alert(1);
}

// 调用函数,返回语法错误。
f();                                 
var f = function(){
    alert(1);
}

这个一看就懂为啥了,在预编译阶段,声明了变量f,而没有为它赋值(匿名函数)。直接调用,肯定出错。

5.总结

JS加载包含预编译和执行两个阶段:

  • 编译阶段,对所有的var变量和function进行扫描,并将var变量初始化为undefined类型,而function则被初始化为函数值。
  • 执行阶段,JS从上面往下面依顺序执行,遇到var变量便进行赋值(因此,在赋值之前进行调用的话会出现错误),遇到函数变量的话会从活动对象中寻找函数
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值