JavaScript 解析器、预解析、变量提升、函数提升

转载请注明预见才能遇见的博客:https://my.csdn.net/

原文地址:https://blog.csdn.net/weixin_42787326/article/details/81328757

JavaScript解析器、预解析、变量提升、函数提升

目录

JavaScript解析器、预解析、变量提升、函数提升

1.JavaScript解析器工作步骤

2.预解析

1.预解析概念

2.预解析做什么事?

3.预解析的注意事项

3.变量提升 和 函数提升

案例1 函数和变量 变量提升

案例2 函数和变量 变量提升

案例3  函数提升

案例4 只有定义会被提升,赋值不会被提升

案例5 函数名字和变量的名字一样 也会被覆盖,函数优先级高

案例6 如果是通过 var 函数名 = function(){} 定义函数,赋值部分的匿名函数不会被提升

案例7 如果把函数的变量写成这样,a会被提升,b不会被提升,这里的变量提升和 var a = function(){}一样


1.JavaScript解析器工作步骤

1.找一些东西:var、 function、 参数、a=未定义  (也被称之为预解析)。所有变量,在正式运行代码之前,都提前赋一个值:未定义undefined   fn1=function fn1(){alert(2);} //所有的函数,在正式运行代码之前都是整个函数块

注:只先找var ,function声明的

  • 遇到变量和函数重名了,只留下函数
  • 遇到函数重名了,根据代码的上下文顺序,留下最后一个,变量也是一样

2.逐行解读代码

备注:表达式可以修改预解析的值

JS解析器在执行第一步预解析的时候,会从代码的开始搜索直到结尾,只去查找var、function和参数等内容。一般把第一步称之为“JavaScript的预解析”。而且,当找到这些内容时,所有的变量,在正式运行代码之前,都提前赋了一个值:未定义;所有的函数,在正式运行代码之前,都是整个函数块。

console.log(a);
var a=1;
console.log(a);
function a(){console.log(2);}
console.log(a);
var a=3;
console.log(a);
function a(){console.log(4);}
console.log(a);

具体过程: 

  • 1.找到第一个var存值为undefined(注意不会为其赋值为1,而是undefined)
  • 2.function a(){console.log(2);}代替前面var
  • 3.var =3不会替代function
  • 4.function a(){console.log(4);}替代function a(){console.log(2);}
  • 5.预解析结果:把a=function a(){console.log(4);}存在预解析的仓库里面

2.预解析

1.预解析概念

  • 预解析就是在解析代码之前,提前解析代码。

2.预解析做什么事?

  • 把变量的声明提前了----提前到当前所在的作用域的最上面
  • 函数的声明也会被提前---提前到当前所在的作用域的最上面

3.预解析的注意事项

  • 预解析中,变量的提升,只会在当前的作用域中提升,提前到当前的作用域的最上面
  • 函数中的变量只会提前到函数的作用域中的最前面,不会出去
  • 预解析会分段(多对的script标签中函数重名,预解析的时候不会冲突)
<script>
function f1() {
  console.log("哈哈");
}
</script>

<script>
    f1();
    function f1() {
      console.log("嘎嘎");
    }
</script>

3.变量提升 和 函数提升

变量使用的时候,把会变量的声明提升到作用域的上面。函数调用的时候,把会函数的声明提升到作用域的上面。

变量提升 提升的只是定义,赋值不会被提升。函数提升也是提升的只是定义,赋值不会被提升。

案例1 函数和变量 变量提升

f1();//调用
var num=20;//这个变量的声明会提升到变量使用之前
function f1() {
    console.log(num);//undefined
}

// 解析
var num;
function f1() {
    console.log(num);//undefined
}
f1();//调用
num=20;//这个变量的声明会提升到变量使用之前

案例2 函数和变量 变量提升

f1();//调用
var num=20;//这个变量的声明会提升到变量使用之前
function f1() {
    console.log(num);//undefined
    var num=10;
}

//解析
var num;
function f1() {
    var num;
    console.log(num);//undefined
    num=10;
}
f1();//调用
num=20;//这个变量的声明会提升到变量使用之前

案例3  函数提升

function f1() {
    console.log("小苏好猥琐");
}
f1();//小苏没有助教猥琐
function f1() {
    console.log("小苏没有助教猥琐");
}
f1();//小苏没有助教猥琐

// 解析
function f1() {
    console.log("小苏好猥琐");
}
function f1() {
    console.log("小苏没有助教猥琐");
}
f1();//小苏没有助教猥琐
f1();//小苏没有助教猥琐

案例4 只有定义会被提升,赋值不会被提升

f1();// f1 is not a function
var f1=function () {
  console.log(a);
  var a=10;
};

//解析
var f1;
f1();// f1 is not a function
f1 = function () {
  var a;
  console.log(a);//
  a=10;
};

案例5 函数名字和变量的名字一样 也会被覆盖,函数优先级高

var a;
function a() {
  console.log('aaaaa');
}
console.log(a);//f

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

案例6 如果是通过 var 函数名 = function(){} 定义函数,赋值部分的匿名函数不会被提升

//如果是通过 var 函数名 = function(){} 定义函数,赋值部分的匿名函数不会被提升
console.log(a);//undefined
var a = function() {
}
console.log(a);//f
var a = 1;
console.log(a);//1

// 解析
var a;
console.log(a);//undefined
a = function() {
}
console.log(a);//f
a = 1;
console.log(a);//1
console.log(a);//undefined
var a = 1;
(function(){
  console.log(a);//1
})();


//解析
var a;
console.log(a);//undefined
a = 1;
(function(){
  console.log(a);//1
})();

案例7 如果把函数的变量写成这样,a会被提升,b不会被提升,这里的变量提升和 var a = function(){}一样

// 如果把函数的变量写成这样,这里的变量提升和 var a = function(){}一样 
 var a = function b() {
   console.log(1);
   //b在当前函数中打印
   console.log(a===b);//true
 }
 a();
 b();// b is not defined

JavaScript解析器、预解析、变量提升、函数提升

博客地址:https://blog.csdn.net/weixin_42787326/article/details/81328757

猜你喜欢

转载自blog.csdn.net/weixin_42787326/article/details/81328757