fayeah / blogs

方法论、问题驱动、总结
6 stars 0 forks source link

【JS】JavaScript的编译和执行 #30

Open fayeah opened 4 years ago

fayeah commented 4 years ago

理解js的变量提升,先看两段代码,查看其输出 : Part1:

showName()
console.log(myname)
var myname = 'name'
function showName() {
    console.log('函数showName被执行');
}
showName()
console.log(myname)
function showName() {
    console.log('函数showName被执行');
}

先保留答案,我们了解几个概念。

变量提升(Hoisting)

JS引擎会把变量和函数的声明部分提升到代码的开头,并给变量一个默认值undefined。Part1代码为例模拟变量提升效果: imageimage

分析:

  1. JS引擎会 将代码分为两个阶段:编译和执行
  2. 编译阶段,以上述代码为例:
    • 将所有 的变量或函数进行变量提升,放在内存中
    • 对于变量,变量提升后将其赋值undefined
    • 对于函数 ,将函数存储在堆(Heap)中,并创建一个showName的变量,将该变量指向堆中函数的位置
    • 编译之后分为两个部分:执行上下文(包括变量环境、词法环境等)和可执行代码
  3. 有了可执行代码,便可以进行执行操作

答案

所以对于最开始的两段代码,我们来分别解答: Part1:

  1. 首先,编译阶段进行变量提升,并产生可执行代码:
    
    // 变量提升的执行上下文
    var myname=undefined
    function showName() {
    console.log('函数showName被执行');
    }

// 可执行的代码 showName() console.log(myname) myname = 'name'

2. 执行可执行代码,
    - `showName`直接打印`函数showName被执行`
    - `myname`此时的值为undefined,还未进行赋值,所以结果为`undefined`

**Part2:**
1. 首先,编译之后结果:

// 变量环境 function showName() { console.log('函数showName被执行'); } // 可执行代码 showName() console.log(myname)


2. 执行: 
    - `showName()`打印出`'函数showName被执行'`
    - 由于没有找到  `myname`变量,所以会报错
![image](https://user-images.githubusercontent.com/29644978/93154636-b11d3f00-f736-11ea-87ce-b559a32a22b3.png)

Note:如果变量或函数出现了同名情况,那么第二个变量或函数会覆盖第一个。

reference: https://time.geekbang.org/column/article/119046