变量声明提升和函数声明提升——个人理解

280 阅读3分钟
第一次写掘金,不为别的,就是因为自己看书记不住东西。写出来算是整理思路也为了自己能更好的诠释出来。如有错误请留言评论,如没有错误也请评论评论,如没有人看到,那我自己过段时间复盘自己评论。**

变量声明提升

var关键子声明一个变量时以下代码不会报错:
function foo (){
  console.log(age);
  var age = 26;
}
foo()   //undefined

这是因为使用这个关键字声明的变量会自动提升到函数作用域顶部,ECMAScript运行时会将foo()看成如下代码:

function foo (){
    var age;
    console.log(age);
    age = 26;
}
foo()  //undefined

这就是所谓的提升,var声明的变量都会拉到当前作用域的顶部。

函数声明提升

据《js高级程序设计第四版》第十章函数中介绍,JavaScript引擎在加载数据时是区别对待的,在任何代码执行前会先读取函数声明,并在执行上下文中生成函数定义,函数表达式则在执行到该行时才会执行上下文并生成函数定义。所以下面代码运行正常:

console.log(sum(10,10));
function sum (a,b){
  return a+b;
}

函数声明会在执行前先被读取并添加到上下文中,这个过程就是函数声明提升,JavaScript引擎会先扫描一遍,将函数声明提升到源代码树的顶部,即使函数定义在调用之后也会将声明提升,但是以下代码会报错:

console.log(sum(10,10));
let sum = function(a,b){
    return a+b;
}

原因是因为函数定义被包含在了变量声明当中,并不是函数声明,所以当上下文执行到console.log()时,并没有sum函数的定义。这和所使用的声明(变量)关键字并无关系。

来两个有趣的面试题吧!

题目一:

foo();
var foo = function(){
    console.log(5)
};
function foo (){
    console.log(4)
};
//5

综上所述,这道题可以理解为:

function foo (){
    console.log(5)
};
var foo;
foo();
foo = function(){
    console.log(4)
}

题目二:

var foo = function(){
    console.log(4)
};
function foo(){
    console.log(5)
};
foo();
//4

综上所述,这道题可以理解为:

function foo(){
    console.log(5)
};
var foo;
foo = function(){
    console.log(4)
};
foo()

哪里有错误,或者理解的不一样留个言,大家一起讨论一哈

2021/8/23

我回来复盘了 函数声明提升和变量声明提升都是提升到函数作用域的顶部。来看看下边的例子吧

image.png 这里怎么会多出一个匿名函数,接着往后看看

image.png 执行到最后一行这个匿名函数还在,看了其他资料,也问了身边大佬,结论是js在解析的时候会把所有js代码放入一个全局的匿名函数里,然后执行这个匿名函数,这个类似于js的入口。所以这个函数就成了全局下最顶部函数,不论函数声明提升还是变量声明提升都是提升到函数作用域的顶部。