几段经典的js代码解析

转来一篇非常有意思的文章:

Dmitry Baranovskiy 的博客中有篇文章(链接),其中有五段小代码,用来测试是否理解JavaScript 的核心,闭包和作用域。大家先试着给出 alert 语句的输出结果。之后再建一个测试文件,检测你的答案。最后再看看我给的解析。

1

if (!("a" inwindow)) {
    var a = 1;
}
alert(a);

2

var a = 1,
    b = functiona(x) {
        x && a(--x);
    };
alert(a);
3

function b(x, y, a) {
    arguments[2] = 10;
    alert(a);
}
b(1, 2, 3);
4
function a(x) {
    returnx * 2;
}
var a;
alert(a);
5
 
function a() {
    alert(this);
}
a.call(null);





----------------------------------------------------------------------------------------我是分割线----------------------------------------------------------------------------------------

答案与解析:

1

答案: undefined。

解析:这个原理叫“变量提升“,简单的说,因为js没有块级作用域,只有函数级作用域,js中的局部变量的声明都会被“提升”至当前作用域的顶端。所以这段代码相当于:

var a;
if (!("a" inwindow)) {
    a = 1;
}
alert(a);


 这样就很好理解了。 

2

答案:1。

解析:这个我还有点疑问,望高人指导。这段代码涉及到了js解释器解释执行代码的过程,因为js和很多其他语言一样,函数定义可以在函数调用之后,说明了解释器在实际执行代码之前已经做了一个”预编译“操作,这个操作的一个目的就是为所有的函数建立一个”符号表“,正因为在执行代码之前已经建立了这个表,所以函数调用可以放在函数声明之前。因此,实际上函数声明那段代码在代码执行前就执行了,所以后来发现a==1,因为a把函数名覆盖了。

3

答案:10。

解析:这个没什么好说的,这个例子就是说明arguments[2]和a就是同一个对象,而不是一个拷贝。这是arguments的一个特性。

4

答案:就是那个函数。

解析:这个题目比较容易答对,即使没有理解变量提升和函数声明的预编译过程。应该改成这样:

var a = 1;
function a() {}
alert(a);
这就比较有迷惑性了。修改后的答案是 1。因为函数声明是在预编译阶段就执行的,然后被 var a=1给覆盖了。注意预编译是肯定比任何代码(包括变量提升)要早的。


5

答案: window。

解析:这个原因应该是call函数的实现中,对参数的判断是,如果参数为null或undefined,就认为没有传参数,而没有传参数的时候上下文显然应该是window。


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值