您的位置:首页 > Web前端 > JavaScript

JAVASCRIPT之词法分析----你真的懂JS吗? 【未完待续】

2014-05-06 11:20 471 查看
先上几道题:

1、

<script>
alert(a);
</script>


<script>
alert(a);
var a = 1;
</script>


2、

<script>
if("a"  in window){
var a = 1;
}
alert(a);
</script>


3、

<script>
function t(g){
alert(g);
function g(){
alert(1);
}
}

t(2);

</script>


4、

<script>
function t(t){
alert(t);
t();
}

t(function(){
alert(t);
});

</script>


5、在不同浏览器上看看效果
<script>
var t = function a(){
alert(a);
}

t();
alert(a);

</script>


谁能做到只分析代码就得出正确结论,并且说明原理, 那么恭喜你,说明你深刻掌握了词法分析的原理。

这五道题的结果可能让很多人感觉到意外,JS虽说是脚本语言, 但是它在执行之前会先做预解析, 也就是词法分析。

词法分析分成三个步骤:

1、检查var声明,

当一段程序或函数在运行前,会为当前作用域创建一个活动对象AO,
检查所有用var声明的变量, 将此变量挂到该AO上,但并不赋值(变量的赋值是发生在代码真正运行时);

2. 函数参数传递,

若这段程序是个函数,JS引擎会将传递的参数赋值给该函数的形参。

3、函数声明

检查当前域中的函数声明,将声明的函数挂到AO上。这样就可以形成一个AO链, 函数声明的形式为:function
aa(){} ,

现在我们再来分析这五道题 。

1, 第一道题中第1小题报错。因为使用了一个未声明的变量。第2小题为undefined,在词法分析中,当前活动对象已有变量a, 只是没有赋值。 所以为undefined.

2、 第二题是想判断a是否为window的属性, 如果是,则a=1, 可是JS引擎会先检查var声明,将a挂到AO上, 然后再运行。 导致代码在运行时, a已经声明, a=1.

3、 第三题当函数t在运行前, 词法分析先检查有没有var声明,没有, 再到参数传递, 将g挂到t的活动对象AO上,并将其赋值为2, 再去检查是否有函数声明, 正好有一个函数名为g的函数声明,先判断AO上是否有g这个变量,如果没有,则创建,没有则覆盖,那么g变成了一个函数。
值为function g(){ alert(1) };

4、第四题有点绕,需要我们了解作用域的概念, 让我们来一起分析下。 当代码在运行前, 首先在window上创建一个AO。将函数t挂到window的AO上。当代码调用函数t时,需要对函数t进行词法分析了,将传过来的参数function(){alert(t)} 传递给参数t,
那么alert(t)得到的结果自然是function(){alert(t)} ,可t()为何却得到

function t(t){

alert(t);

t();

}

匿名函数function () { alert(t); } 是在哪里定义的, 是在最外层的window上。 此匿名函数用到了变量t, 在该匿名函数中找不到变量t,那么就会往它的上一级去找。它的上一级是谁,
是window而不是运行时的t, window上正好有个变量为t.

如下图:

这个例子也正说明: 变量的值取决于声明时的环境而不是运行时的环境,这是与其它语言最大的不同。

如还不理解,可以再看看这题:

<script>
var a = 1;
function t(g){
var a = 2;
g();
}

t(function(){
alert(a);
})

</script>


5、第五题,函数表达式
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐