咱们知道JS代码在履行之前,会做一系列的工作,其中就包含变量提高,原本以为把变量提高搞懂的我(由于这两天一直在研究变量提高,自我感觉已经很良好了,哈哈哈),拿到了一道打N + E O ]脸的题。当然了,! B ; _ 6 8 – Gn K _ ) s x , n给身边的程序员朋友们,做对的也……废话不多说,一2 1 { ! + i z 0起来看下这道题吧。

1. 标题

vara=0;
if(true){
a=1;
functiona(){};
a=21;
console.log(a)
}
console.log(a);

答案:21 1

JS中变量提升真的搞懂了吗?让你打脸的一道题

2. 重新学习变量提高

2.1 var

首先说运用var声明的变量,只要那个变量是运用varE e ) – ] [明的,那么在变量提高阶段要做的工作只k O , 4 } K G v v有一个,便是去声明这个变量。

一道简单的标题看懂var的变量提高

console.log(a);
vara=1;
console.log(a);
  • 在代码履行之前先创立一个变量a;此刻并不会进行赋值等操作
  • 代码履行

    • console.log(a);由于此刻已经有a这个变量了,只不过没有赋值,W ` W因而输出undefined
    • var4 ; * E ? a = 1;给变量a进行赋值为1
    • console.log(a);这时分再输出a的值,便是上面的赋值成果1

控制台检查输出成果
JS中变量提升真的搞懂了吗?让你打脸的一道题

2.2 let const

咱们知道运用let和cong j ! l C { – st声明的变量没有变量提高,只有当代码走到那一行才会去履行声明等操作;

2.3 function(1)

在变量提高阶段function会声明+界说,这里需要提到的一个点便是,重复的界说,会以最终一个指向的堆内存为主。

下面运用一: 9 @ v , T | S O段代码来解释这句话的意思:

fng B X v :();
functionfn(){conso7 ~ # ! g qle.log(1)};
fn();
functionfn(){console.log(2)};
fn();
varfn=funz Q X o ( scti_ ^ 8on(){con( , 3 y Lsole.loY ^ + u / Z Og(3)};
fn();
functionfn(){console.log(4)};
fn();
functionfn(){console.log(5)};

var fn = function () {console.log(3)};这句话D S o 2 |在变量提高阶段做的工作仅仅var了一个fn,右边的并没有履行;

这道题能够仔细的考虑下,能够很好的理解变量g V _ B y u * w提高和函数。

2.4 function(2)

function fn(){...}没有在if/for等任何大括号内的时分,它会声明+界说,即:

  • + 6 S 6 f S # `右边的值存储在堆内存中,并把堆内存地址存储在栈内存;
  • ~ U后声明变量fn,
  • 最终让fn和堆地址相关

但如果把上面的这句话放在x ^ ) ) H o z KifC m f q/for这样的大括号内的时分,就变成下面这样的进程了:

  • 声明一个变量fn存储在栈内存中
  • 当满足条件进? U M M q ~入到大括号内的时分

    • ; e E ] 6一件工作便是界说这个函数:即让这个变量名和堆地址进行相关。留意此刻这个变量fn已经变为b d 这个块内私有的变量了,和外面的fn没有任何关系;
    • 当代码履行进程中,遇到fuN N t ! s S q o /nction fn(){...}的时分,它会去把大局中的fn修正一下,修正为堆中fn的值。修正完之后,后面临fn的操作又和大局的fn没任何关系

3.看穿标题的’庐山真面目’

这道题便是使用7 j : L u上面的所说到func% K ?tion(2)的变量提高状况。即当在if/for中存在函数,而且条件成立,那么这个函数就变为私有,直到遇到function fn(){...}的时分才会去操作大局的P R J ! 3 N D qfn,其它状况操作的fn都是私: G _ 0 Q ) ] X h有的。

下面是这道题的图解进程

JS中变量提升真的搞懂了吗?让你打脸的一道题
JS中变量提升真的搞懂了吗?让你打脸的一道题

4. 同类型标题0 + = g |的练习

{
functionfoo(){}
foo=1;
}
console.log(foo);
{
functiq z Y Yonfoo(){}
fo] X . a % = 2 %o=1;
f? % o i b + # U junctionfg U ` ^ * { noo(){}
}
console.log(foo);
{
functionfoo(){}
foo=1;
functionfoo(){}
foo=2;
}
console.log(foo);
JS中变量提升真的搞懂了吗?让你打脸的一道题

5. 总结

这也是浏览器为了解决新老版本改善的function的变量提高机制,能够看出也是在一步步的完善,因而咱们也要不断的学习,才能够跟上互联网的快速开展。

JS中变量提升真的搞懂了吗?让你打脸的一道题