当前位置:首页 > Web开发 > 正文

js 词法分析,词法感化域

2024-03-31 Web开发

先来看个常见的面试题如下:

var a = 10; function test(){ alert(a); //undefined var a = 20; alert(a); //20 } test();

疑问:为什么呢?test()执行时,虽然a=20没有赋值,但是父级感化域里是有a=10的,不应该是undefined呀,js是按挨次执行的,此时的var num = 20;根柢没有执行,所以应该是10!!你是不是也是这么认为的,就和我当月朔样???

分析:众所周知,js代码是自上而下执行的,JavaScript并不是传统的块级感化域,而是函数感化域。JavaScript引擎会在代码执行前进行词法分析,所以事实上,js运行分为此法分析和执行两个阶段。

JavaScript代码运行前有一个类似编译的过程即词法分析,词法分析主要有三个法式:

分析参数

再分析变量的声明

分析函数声明

具体法式如下:

函数在运行的瞬间,生成一个勾当东西(Active Object),简称AO

第一步:分析参数:

函数接收形式参数,添加到AO的属性,,并且这个时候值为undefined,即AO.name=undefined

接收实参,添加到AO的属性,笼罩之前的undefined

第二步:分析变量声明:如var name;或var name=‘mary‘;

如果上一步分析参数中AO还没有name属性,则添加AO属性为undefined,即AO.name=undefined

如果AO上面已经有name属性了,则不作任何改削

第三步:分析函数的声明:

如果有function name(){}把函数赋给AO.name ,笼罩上一步分析的值

分析下面这个栗子:

1.var a = 10; 2.function test(a){ 3. alert(a); //function a (){} 4. var a = 20; 5. alert(a); //20 6. function a (){} 7. alert(a); //20 8. } 9. 10.test(100);

词法分析:

第一步,分析函数参数:

形式参数:AO.a = undefined 接收实参:AO.a = 100

第二步,分析局部变量:

第4行代码有var a,但是此时已有AO.a = 100,所以不做任何改削,即AO.a = 100

第三步,分析函数声明:

第6行代码有函数a,则将function a(){}赋给AO.a,即AO.a = function a(){}

执行代码时:

第3行代码运行时拿到的a时词法分析后的AO.a,即AO.a = function a(){}; 第4行代码:将20赋值给a,此时a=20; 第5行代码运行时a已经被赋值为20,功效20; 第6行代码是一个函数表达式,所以不做任何操纵; 第7行代码运行时仍是20;

ps:

1.var a = 10; 2.function test(a){ 3. var a; //证明词法分析第二步。 4. alert(a); //100 5. a = 20; 6. alert(a); //20 7.} 7.test(100);

ps:

var a = 10; function test(a){ alert(a); //100 var a = 20; alert(a); //20 a = function(){} //是赋值,只有在执行时才有效 alert(a); //function(){} } test(100);

ps:(执行功效同上)

var a = 10; function test(a){ alert(a); //100 var a = 20; alert(a); //20 var a = function(){} //是赋值,只有在执行时才有效 alert(a); //function(){} } test(100);

增补说明:函数声明与函数表达式

//函数声明 function a(){ } //函数表达式 var b = function(){ }

a和b在词法分析时,区别:

a在词法分析时,就阐扬感化; b只有在执行阶段,才阐扬感化。

词法感化域

所谓词法感化域是说,其感化域为在界说时(词法分析时)就确定下来的,而并非在执行时确定。口语就是在函数未执行前,函数执行的挨次已经被确定,而不是类似JAVA一样,是在执行前根柢不知道执行挨次。

js 词法分析,词法感化域

温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/31216.html