转载请注明预见才能遇见的博客:https://my.csdn.net/
原文地址:https://blog.csdn.net/weixin_42787326/article/details/81328757
JavaScript解析器、预解析、变量提升、函数提升
目录
案例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