当前位置: 首页 > Web前端 > HTML

JavaScript为什么要进行变量提升,会导致什么问题?

时间:2023-03-29 13:02:51 HTML

前言欢迎来到“前端进阶圈”公众号,一起探索和学习前端技术……前端小菜鸟,分享的文章纯属个人观点,如有不妥,敬请谅解可以讨论欢迎大家评论交流,和同学一起学习~JavaScript为什么需要变量提升,会带来什么问题?无论是在那个位置声明的函数还是变量,都会在函数之前被提升,这样可以保证变量在声明之前就可以访问,不会出错。变量提升的本质:js引擎在代码执行前有一个解析过程,有一个执行Context,初始化一些代码执行需要的参数。当访问一个变量时,会在当前执行上下文的作用域链中查找,作用域链的头部指向当前执行上下文的变量对象。这个变量对象是执行上下文的一个属性,它包含了函数参数,所有的函数和变量声明,这个对象是在解析代码时创建的。代码执行过程:解析阶段:JS会检查语法并预编译函数。解析时,会先创建一个全局的执行上下文,先取出代码中即将执行的变量和函数声明。变量首先被赋值为undefined,函数首先被声明并准备好使用。在一个函数执行之前,也会创建一个函数执行上下文,它和全局执行上下文类似,但是函数执行上下文会多出this、arguments和函数参数。全局上下文:变量定义、函数声明函数上下文:变量定义、函数声明、this、arguments执行阶段:按代码顺序执行为什么要进行变量提升?提高性能:在代码执行之前,会进行语法检查和预编译。此操作只会执行一次。这样做是为了提高性能。如果没有这样的步骤,则必须在每次执行代码之前重新编译变量和函数。这个不是必须的,因为变量和函数的代码基本不会变,解析一次就够了。更好的容错性a=1;vara;console.log(a);//1S(Summary):解析和预编译时的Statementpromotion可以提高性能,让函数在执行时为变量预分配栈空间Statementpromotion也可以提高JS代码的容错性,这样一些不规范的代码也可以导致正常执行引起的问题:vartmp=newDate();functionfn(){console.log(tmp);如果(假){vartmp='你好世界';}}fn();//undefined/***在这个函数中,外层的tmp变量本来是想打印出来的,但是由于变量提升的问题,*内层定义的tmp在函数的最上面提到相当于覆盖了外层的tmp,所以打印结果是undefined。*/for(vari=0;i<3;i++){setTimeout(()=>{console.log(i);},2000);}//333for(leti=0;i<3;i++){setTimeout(()=>{console.log(i);},2000);}//012/***由于遍历时定义的变量i会被提升为全局变量,所以会end在函数结束后不会被销毁,*因此,之前定义的全局变量总是被修改,所以第一个输出三次3,第二个输出012*//***在for循环中,let声明的变量会有块作用域的概念。当使用let声明的迭代变量时,*js引擎会在后台为每一次迭代循环声明一个新的迭代变量,所以每次使用时i都是不同的。*/文章特殊字符描述:问号Q:(问题)答案标记R:(结果)注释标准:A:(注意事项)详细描述标记:D:(详细信息)摘要标记:S:(摘要)分析注释:ana:(分析)提示注解:T:(tips)往期回顾:热门面试题:浏览器和Node的宏任务和微任务?这就是你理解的CSS选择器权重吗?面试热点:JS中call、apply、bind的概念、用法、区别和实现是什么?热门面试题:常见的位运算有哪些?Vue数据监控Object.definedProperty()方法的实现面试热点问题:VirtualDOM相关问题?面试热点问题:Array中的无损方法有哪些?面试热点:协商缓存和强缓存的理解和区别?最后:欢迎大家关注“前端进阶圈”公众号,一起探索学习前端技术...公众号回复加群或扫码,即可加入前端交流学习群,长期交流学习.....公众号回复加好友,可以加为好友