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

js词法分析,词法作用域

时间:2023-04-02 20:29:25 HTML

先来看一道常见的面试题如下:vara=10;functiontest(){alert(a);//未定义的变量a=20;警报(一);//20}测试();问题:为什么?执行test()时,虽然a=20没有赋值,但是父作用域中有a=10,应该不是undefined,js是按顺序执行的,此时varnum=20;它根本没有执行,所以它应该是10!!你是不是和我一样这么认为???分析:众所周知,js代码是自上而下执行的。JavaScript不是传统的块级作用域,而是函数作用域。JavaScript引擎在代码执行之前会进行词法分析,所以其实js的运行分为两个阶段:分析和执行。在JavaScript代码运行之前,有一个类似于编译的过程,即词法分析。词法分析主要有三个步骤:分析参数,然后分析变量的声明。简称AO第一步:分析参数:函数接收形参,添加到AO的属性中,此时值为undefined,即AO.name=undefined接收实参,添加到AO的属性中AO,并覆盖掉之前的undefinedStep2:分析变量声明:如varname;或varname='mary';如果上一步分析参数中的AO没有name属性,则将AO属性添加为undefined,即AO.name=undefined如果AO上已有name属性,则不做任何改动.第三步:分析函数的声明:如果有functionname(){},将函数赋值给AO.name,覆盖上一步分析的值。分析下面的栗子:1.vara=10;2。功能测试(a){3.警报(a);//函数a(){}4.vara=20;5.alert(a);//206.functiona(){}7.alert(a);//208。}9.10.test(100);词法分析:第一步,分析函数参数:形式参数:AO.a=undefined接收实参:AO.a=100第二步,分析局部变量:第4行代码有vara,但是AO.a=100已经此时存在,所以不作修改,即AO.a=100第三步分析函数声明:第6行代码有函数a,然后将函数a(){}赋值给AO。a,即AO.a=functiona(){}代码执行时:第三行代码运行时,得到词法分析后的AO.a,即AO.a=functiona(){};第4行代码:将20赋值给a,此时a=20;第5行代码赋值20,结果为20;第6行代码是一个函数表达式,所以什么都不做;第7行代码运行时还是20;ps:1.vara=10;2.functiontest(a){3.vara;//证明词法分析其次步骤4.alert(a);//1005。一=20;6。警报(一);//207.}7.test(100);ps:vara=10;functiontest(a){alert(a);//100变量a=20;警报(一);//20a=function(){}//是一个赋值,只在执行时有效alert(a);//函数(){}}测试(100);ps:(执行结果同上)vara=10;功能测试(a){警报(a);//100变量a=20;警报(一);//20vara=function(){}//是赋值,只有执行时有效alert(a);//函数(){}}测试(100);补充说明:函数声明和函数表达式//函数声明functiona(){}//函数表达式varb=function(){}a和b在词法分析时是有区别的:a在词法分析时起作用;a在词法分析时起作用;b只在执行阶段起作用。词法作用域所谓词法作用域是指它的作用域是在定义时(词法分析时)确定的,而不是在执行时确定的。大白话就是在函数执行之前,函数执行的顺序就已经确定了,而不是像JAVA那样,在执行之前根本不知道执行顺序。