侧边栏壁纸
博主头像
工作笔记

若批评无自由,则赞美无意义。

  • 累计撰写 190 篇文章
  • 累计创建 206 个标签
  • 累计收到 20 条评论
标签搜索

目 录CONTENT

文章目录

Javascript中,浅谈对var变量提升的理解

工作笔记
2022-11-17 / 0 评论 / 0 点赞 / 239 阅读 / 1,372 字 / 正在检测是否收录...
温馨提示:
🌝 免责声明:本文存在此处完全是为了方便个人工作记录学习,不存在任何商业利益信息。若不小心影响到您的利益,请联系首页博主信息中公开的邮箱,博主将进行删除处理。谢谢合作!

前提

众所周知啊,变量提升和函数提升基本上是面试必问,是基础中的基础。那么变量提升到底是个啥呢?通俗点讲,就是在JavaScript里啊,函数和变量的声明总是会被提升到当前作用域的最顶端。
看下面的例子:

// 第一个小例子
a = 1;
var a;
console.log(a);//输出 1

// ???为什么输出1呢 按照程序自上而下的执行的概念,不应该输出undefined吗!!

// 第二个小例子
console.log(b);
var b = 2;

// 你觉得这个例子运行是报错还是输出2呢?

首先我们来解析一下第一个例子,按照程序自上而下的执行的概念,应该输出undefined。但是,JavaScript并不是一门严格的自上而下执行的语言。为什么这么说呢?原因就来源我们今天讲的变量提升。 其实根据变量提升,第一个例子可以看成以下代码:

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

这样子就好理解了吧。然后我们看看第二个例子,你觉得它是报错还是输出2呢?其实都不是,它会输出undefined,因为在前面我们说了,变量提升是提升变量的声明,而非变量的赋值,而对于JS来说,以下代码是等价的。

var b = 2;
//上下代码其实是等价的
var b;
b = 2;

所以它会输出undefined。

分析原因

想要知道原因,我们首先得知道JavaScript在运行时经历了什么。
其实在JavaScript运行时,一共经历了两个阶段:

  • 预编译阶段
  • 执行阶段

任何代码运行前都会经历预编译阶段,但它占用的时间往往极其短暂,所以我们一般感知不到,它主要是在内存中开辟一些空间以此来存放变量与函数。预编译时,JS会搜集所有的变量声明并且提前声明变量,而其他的语句都不会改变他们的顺序,并且,变量提升后,会给变量设置默认值undefined,给函数赋值函数体。所以你可以认为,预编译后,代码中的变量声明全部被提升到代码开头,其他代码位置不变。

逐渐深入

上面我们的例子只引入了变量,现在我们再来尝试引入函数。首先看下面这个例子

a();

function a() {
    console.log('a');
}
var a = 1;

你觉得它会输出什么呢?他是不是等同于

var a;
function a() {
    console.log('a');
}
a();
a = 1;

乍一看,你是不是觉得这肯定undefined啊!但是它还是输出了a,究其原因,就是当函数声明与其他声明一起出现的时候,函数声明高于一切,因为函数是JS的“第一公民”。
了解完之后,我们再看一个例子。

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

它变量提升后是什么样子呢?

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

showName();

这里的输出结果,我们来推导一下:

  • 首先根据函数是JS的第一公民,第一个showName()读取到的应该是showName = function() { console.log(1);}此时输出1。

  • 然后代码继续向下运行,showName()读取到 function showName() { console.log(2); }将一开始读取的 function showName() { console.log(1); }覆盖,从而在最后一行的showName()输出2。 所以它的输出结果为1 2。

  • 解决了这些问题,又有一个疑问出现了,既然函数是JS的“第一公民”,那么当多个同名函数同时声明时,具体会发生什么呢?让我们看看下面的代码:

showName();

function showName() {
    console.log('a');
}

function showName() {
    console.log('b');
}

它的输出结果为 b 。 为什么呢?因为在有多个函数声明时,最后面的函数声明会替代前面的函数声明。

总结

从上面这些例子分析啊,我们可以总结3个小tips:

  • 所谓的变量提升(变量提升),是指在JS代码执行中, JavaScript引擎(V8)把变量的声明部分和函数的声明部分提升到代码开头的行为,变量提升后,会给变量设置默认值undefined,给函数赋值函数体。
  • 在JS的变量提升中,提升的只是变量的声明,所以对于var a = 1,一般把它拆分成var a 和 a = 1。只提升var a,a = 1不变。
  • 有多个同名变量声明时,函数声明会覆盖其他的声明。如果有多个同名函数声明,则是由最后的一个函数声明覆盖之前所有的声明。

如有侵权,请联系删除。

作者:叨叨不是刀刀
链接:https://juejin.cn/post/6951223024053911560
来源:掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

0

评论区