JavaScript预解析:同名变量和函数、同名函数表达式和同名函数声明

预解析的含义:在写js代码调用函数的时候,无论你是在调用位置的前面或者后面声明函数,都可以正常调用,

原因是,JavaScript碰到script标签,会将var变量(注意是var)声明函数声明(注意是声明)提升到当前作用域最前面

预解析结论变量的提升,指的是声明的提升,赋值(初始化)并不会提升

看一些例子:

例1:

//例1
console.log(num);  
var num = 2;

//上述代码:解析过程
var num;            //第一步:预解析       
//执行过程
console.log(num);   //第二步:打印结果-->undefined
num = 2;            //第三步:赋值

说明:变量声明提升,赋值不提升

例2:

//例2:
var num = 2;
var num;
console.log(num);

//上述代码:解析过程
var num;    //第一步:预解析
var num;    //第二步:预解析
num = 2;    //第三步:赋值
console.log(num);   //第四步:打印结果-->2

结果不是undefined?因为var 变量是会提升的,提前预解析了,然后又赋值了,所以结果为2。

扩展-1:

//扩展-1
function f() {}
var f;
console.log(f);  

//上述代码:解析过程
function f() {} //第一步:预解析整个函数
var f;          //第二步:预解析
console.log(f); //第三步:打印结果-->function f() {}

按理说,这里应该是undefined,结果不是

原因:预解析时,当变量和函数同名时,优先留下函数的值(不管谁前或后,函数优先级更高)

扩展-2:

//扩展-2
function f() {
    console.log(num); // undefined
}
var num;

这里函数里面能访问到num,证明变量的声明会在函数声明之前

这个问题是个人的理解,有疑问的读者也可以去查些资料。 

例3:

//例3
var f = function() {
    console.log(1)
 }
 function f() {
   console.log(2)
 }
 f();  

//上述代码:解析过程
var f;                          //第一步:预解析
function f() { console.log(2)}  //第二步:预解析--f整个函数
f = function() { console.log(1)}//第三步:f赋值整个函数
f();                            //第四步:执行函数f-->输出1

例4

//例4
f();  
var f = function() {
  console.log(1)
}
function f() {
  console.log(2)
}
f(); 

//上述代码:解析过程
var f;                          //第一步:预解析
function f() { console.log(2)}  //第二步:预解析--f整个函数
f();                            //第三步:执行f函数-->输出2
f = function() { console.log(1)}//第四步:f赋值整个函数
f();                            //第五步:执行f函数-->输出1

这个例子和前一个只是函数调用位置发生了改变,结果也变了

例5:

//例5
f(); 
var f = function(){
    console.log('k')
}

//上述代码:解析过程
var f;                              //第一步:预解析
f();                                //第二步:执行f函数,报错
f = function(){ console.log('k')}   //第三步:f赋值整个函数

原因:调用一个未赋值的函数,当然会报错,

注意:这个例子,将函数表达式换成函数声明就不会报错了,

          因为函数声明会提升,这也是我们常用函数声明的一个原因,可以在任何位置调用。

例6:

//例6
var num = 2;
function f() {
  num = 1;
  console.log(num)  
  return
  var num = 3;
}
f();
console.log(num); 

//上述代码:解析过程
var num;                //第一步:预解析
function f() {          //第二步:预解析--f整个函数
    //解析过程
    var num;            //此处提升的变量是return后面的
    num = 1;            //num赋值
    console.log(num)    //执行时,会输出1 
    return              //后面的代码不会执行
    num = 3; 
}
num = 2;                //第三步:num赋值
f();                    //第四步:执行f函数-->输出1
console.log(num);       //第五步:输出结果-->2

说明:return后面的语句虽然不会执行,但是变量还是会提升,所以f函数执行时,会输出1

例7:

//例7
console.log(num);  //报错
num = 2;

  只有var会提升,隐式全局变量并不会提升,所以结果和例1不同,并不是undefined

本文引自:https://blog.csdn.net/m0_37897013/article/details/81701016

其它可借鉴的资料:https://www.jb51.net/article/90113.htm

原文地址:https://www.cnblogs.com/ggll611928/p/13156966.html