你真的了解JS变量提升吗

407 阅读2分钟

变量提升

在JS代码执行前,会执行词法分析,所以JS 代码执行过程分为两个阶段:

词法分析 :词法分析主要包括:分析变量声明、分析函数声明、分析形参三个部分

执行阶段

变量提升

变量提升,是JS一个重要知识点,也是面试常考点,我们先看下下面这道题:

var a = 0;
if (true) {
    a = 1;
    function a() {};
    a = 2;
    console.log(a)
}
console.log(a);
查看答案 2 1

有答对吗?

var 提升

var 声明的变量会提升

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

上面的代码相当于如下的代码:

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

1、在代码执行之前先创建一个变量a;此时并不会进行赋值等操作;

2、console.log(a);因为此时已经有a这个变量了,只不过没有赋值,因此输出undefined;

3、var a = 1;给变量a进行赋值为1;

4、console.log(a);这时候再输出a的值,就是上面的赋值结果1;

函数声明的提升

function fn(){}
  • 把函数右边的值存储在堆内存中,并把堆内存地址存储在栈内存
  • 然后声明变量fn
  • 最后让fn和堆地址关联

有条件的创建函数

if(true){
  function fn(){}
}
  • 声明一个变量fn存储在栈内存中
  • 当满足条件进入到大括号内的时
  • 定义这个函数,即让这个变量名和堆地址进行关联。注意此时这个变量fn已经变为这个块内私有的变量了,和外面的fn没有任何关系。
  • 当代码执行过程中,遇到function fn(){...}的时候,它会去把全局中的fn修改一下,修改为堆中fn的值,修改完之后,后面对fn的操作又和全局的fn没任何关系;
var a = 0;
if (true) {
    a = 1;
    function a() {};
    a = 2;
    console.log(a)
}
console.log(a);

所以大家再理解一下这道题。

块级函数

从ECMAScript 6开始,在严格模式下,块里的函数作用域为这个块。ECMAScript 6之前不建议块级函数在严格模式下使用。

'use strict';
function f() {
  return 1;
}
{
  function f() {
    return 2;
  }
}
f() === 1; // true
// f() === 2 in non-strict mode

参考文献:

developer.mozilla.org/zh-CN/docs/…

developer.mozilla.org/zh-CN/docs/…