当前位置:网站首页>JS代码预编译
JS代码预编译
2022-08-04 05:26:00 【strongest强】
JS代码执行过程
语法检查
- 当代码语法出现错误,比如英文逗号(,)写成了中文逗号(,),英文冒号(:)写成了中文冒号(:)等等 。此时 ,控制台就会报错语法错误。
预编译
- 预编译有全局(GO)和局部(AO)预编译,此时会分别创建一个对象。全局预编译发生在HTML执行完后,才会开始编译,而局部预编译是发生在函数执行前。
了解函数的类型
- 函数声明式
function fun(){} - 函数表达式
var fn=function(){} - 通过
new Function()构造的函数对象
- 函数声明式
了解变量提升
- 函数声明式,它会自动提升自己的位置,处在当前作用域下的最前面(等下上代码演示)。
- 函数表达式 ,比如
var fun2=function(){}不会将fun2=function(){}提到最前面 ,只是会将 fun2这个变量放在最前面。我们都知道var 可以提升变量,但是它的值在最作用域最前面下是undefined,而不是function(){}这个匿名函数,只有代码执行到这句话,此时fun2才会等于function(){}这个匿名函数
- 全局变量(定义在window下的var变量)和函数声明式,会先在window下最前面,值为undefined。而局部作用域下的var声明的变量和函数声明式,也会和window下声明的一样,只不过局部函数,会比window多一步操作,将传进来的实参和形参统一。
- 在AO和GO下所有函数声明式的属性名(key)作为AO或GO属性,值(value)为函数的内容。
代码执行
- 做完上述预编译操作后,代码就将执行,直到结束。
代码示例
GO变量提升
console.log(v1); let v1 = 'hello1'; --------------------------------- console.log(v2); const v2 = 'hello2'; --------------------------------- console.log(v3); const v2 = 'hello3'; console.log(v3) --------------------------------- console.log(fn1); console.log(fn2); function fn1(){ console.log('我是fn1'); } var fn2=function (){ console.log('我是fn2'); } console.log(fn2);- v1输出 Uncaught ReferenceError: Cannot access ‘v1’ before initialization,可见let不可以提升变量
- v2输出 Uncaught ReferenceError: Cannot access ‘v2’ before initialization,可见const也不能提升变量
- v3先输出undefined,后输出hello3。相当于
var v3;v3='hello3' - 输出fn1,可见打印处了
f fn1(){ console.log('我是fn1'); } - 输出fn2,可见先打印了undefined,虽然fn2提升了变量,但是并没有赋值,默认值为undefined,只有执行完这
fn2=function(){}这一行,然后才会打印f (){ console.log('我是fn2'); }
AO变量提升
function fn3(a) { console.log(a);//log1 var a = 1; console.log(a);//log2 console.log(fn5);//log3 function a() { console.log('我是a'); } console.log(a);//log4 var fn5 = function () { console.log('我是fn5'); } a = 10; console.log(fn5);//log5 console.log(a);//log6 } fn3(3);- log1这行先输出
ƒ a() { console.log('我是a'); } - log2这一行输出1
- log3这一行输出undefined
- log4这一行输出1
- log5这一行输出
ƒ () { console.log('我是fn5'); } - log6这一行输出10
- 此时的你是不是心态爆炸?你是不是觉得log1这一行应该输出1,而不是
ƒ a() { console.log('我是a'); }?log4这一行应该输出ƒ a() { console.log('我是a'); },而不是1?我相信大家对于log3和log5这两行应该是懂了的。我知道大家的疑问,毕竟作者原先我就这么和大家认为的一样,避免大家的苦恼,就让我再给大家捋一遍。 - 首先,AO会创建一个对象{},然后将可以提升的变量名放在这个对象中,作为属性。因此首先会有
{ a:undefined, fn5:undefined } - 随后,将传入的实参与形参统一,AO对象会有{a:1,fn5:undefined}
- 最后,会将函数的内容作为属性的值,会将实参传入的值进行覆盖,因此AO对象会有{a:function(console.log(‘我是a’)),fn5:undefined}。这是预编译做的所有事请,然后就执行代码
- 执行的代码就相当于
function fn3(a) { a=function(){ console.log('我是a') } var fn5; console.log(a);//ƒ a() {console.log('我是a');} a = 1; console.log(a);//1 console.log(fn5);//undefined console.log(a);//1 fn5 = function () { console.log('我是fn5'); } a = 10; console.log(fn5);//ƒ () {console.log('我是fn5');} console.log(a);//10 } fn3(3);总结
代码执行就相当于就我写的实例最后的转换。并且,我们要知道只有var声明的变量,以及函数声明式可以提升代码的位置。但是用了var 声明的变量,提升到作用域的最前面,值为undefined,只有函数声明式,才可以输出它自身。
结束语
如果本文对大家有所帮助,不防给个赞,来个收藏,并且评论评论,给他人带来更大的动力。
- log1这行先输出
边栏推荐
猜你喜欢
随机推荐
JNI基本使用
8款最佳实践,保护你的 IaC 安全!
企业需要知道的5个 IAM 最佳实践
DP4398:国产兼容替代CS4398立体声24位/192kHz音频解码芯片
梳理CamStyle、PTGAN、SPGAN、StarGAN
OpenCV获取和设置图像的平均亮度
力扣:62.不同路径
注意!软件供应链安全挑战持续升级
MySql data recovery method personal summary
C1认证之web基础知识及习题——我的学习笔记
8、自定义映射resultMap
部署LVS-DR群集【实验】
力扣:343. 整数拆分
7. Execution of special SQL
Code Refactoring: For Unit Testing
Resolved error: npm WARN config global `--global`, `--local` are deprecated
The Road to Ad Monetization for Uni-app Mini Program Apps: Full Screen Video Ads
力扣题解8/3
TensorRT例程解读之语义分割demo
力扣:509. 斐波那契数









