Javascript的预解析

本文详细介绍了JavaScript的预解析机制,包括全局环境的创建、函数参数和变量声明处理、实参与形参的对应、函数声明的执行,以及闭包和this指向的相关内容,帮助读者理解变量提升现象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

在学习JavaScript时你可能有很多疑惑。例如先打印变量然后声明变量,打印不会报错,有或是先执行函数,然后声明函数,却能正常执行等等。这正是因为Javascript在执行前有一预解析的过程。本浅谈一下预解析。


一、全局环境 

Javascript是一种脚本语言,必须要在执行环境下执行。浏览器下Javascript引擎,node的v8引擎。 

脚本运行执行前会产生一个全局执行环境,在此环境下变量称为全局变量。声明的函数也会在全局环境中。

var a = 123;
b = 234;
function fn() {
  c = 456;
  console.log(123);
}
// window就是全局环境对象 在全局环境下声明的变量和函数都会成为window对象的属性
console.log(window.a); // 123

// 隐式的声明
console.log(window.b) // 234

// 在之前的浏览器这里应该是 456 应该是javascript引擎优化了。
console.log(window.c) // undefined

console.log(window.fn); // ƒ fn() { console.log(123); }

二、局部环境

Javascript在ES6之前没有块级作用域的概念. Javascript是函数作用域的。在函数里面声明的变量变量和函数表达式都是局部的。这里可能涉及到了作用域和作用域链的概念。后续待讲解。 

三、预解析

在讲解预解析前我们看看一段代码

function fn(a) {
  console.log(a);

  var a = 123;

  console.log(a);

  function a() {}

  console.log(a);

  console.log(b);

  var b = function () {};

  console.log(b);

  console.log(d());

  function d() {
    console.log("执行d函数...");
  }
}

fn(1);

 初学Javascript的看到上述代码估计脑子很乱,不清楚每个console.log打印的结果。不急通过预解析就能了解Javascript执行过程了。

1. 生成全局环境

Javascript在运行前一刻会立刻生成一个全局执行环境。生成一个全局执行上下文对象,称为global object. 将fn成为window的一个属性。

// global object 将 GO 下面是伪代码 便于理解

GO: {
  fn: function() {}
}

2. 在fn执行前预解析

 全局环境生成完毕后,对fn(1)函数进行预解析。预解析基本分为四个步骤

1. 创建AO(Activation object 执行期上下文对象)对象;

AO: {

}

2. 找到形参和变量声明 将变量和形参名作为AO属性名,值为undefined;

 形参: 第1行括号里的 a;

变量声明:第4行 a 第15行的b 

AO: {
  a: undefined
  b: undefined
}

3.将实参值和形参统一

实参为1, 会将AO中的a的值改为实参的值

AO: {
  a: 1
  b: undefined
}

4. 在函数体里面找到函数声明,值赋予函数体。

此时fn中有两个函数声明:第8行和第20行。注意第14行不是函数声明是函数表达式。

AO: {
  a: function () {}
  b: undefined,
  d: function () {}
}

四 执行代码

预解析完后,将逐行执行。在执行时会从执行上下文中对象中获取需要的变量或者函数。还有赋值。

第2行 打印 a() {}

第4行 会将AO中a的值改为123

AO: {
  a: 123
  b: undefined,
  d: function () {}
}

第6行 打印 123

第10行 打印123

第12行 打印 undefined

第14行 将函数体赋值给AO的b

AO: {
  a: 123
  b: function () {},
  d: function () {}
}

第16行 打印 b() {}

第18行 打印执行d函数 其实在此还会产生一个执行上下文。这个就关于闭包的知识了


总结

本文主要讲解了Javascript的预解析的过程。了解了预解析的过程。对于一些变量或者函数的提升就豁然开朗。其实预解析还做了很多复杂的事情。例如this的指向产生、作用域以及作用域链等等。希望对你有所帮助。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值