你自认为理解了JavaScript?

发表于:
标签:
编辑 删除

引用

  1. 你自认为理解了JavaScript?
  2. So, you think you know JavaScript?

文章来自 CSDN 论坛 Javascript 版的置顶贴 《你自认为理解了JavaScript?》,该帖内容主要参考了 Dmitry Baranovskiy 的博文 So, you think you know Javascript?, 有五段小代码,用来测试是否理解 JavaScript 的核心,闭包和作用域。

看了看,自己有两道不能确定答案。就参考后边的评论,再加上后来重新查阅了 MDN 上面的一些资料,本文就做个记录。

代码 1:

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

这个需要我们理解 Javascript 中的 hoisting 概念,也就是 Javascript 在解析代码时,会自动将所有的变量声明提升到代码最开始。所以上面的代码等价于:

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

所以答案很显然就是 undefined

代码 2:

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

这里主要需要理解的是 b 使用了函数定义表达式(Function Definition Expression)来声明的。而函数定义表达式通常使用的是匿名函数,如:

b = function(x) {
   x && a(--x);    
}

其实也可如代码2中一样,使用非匿名函数。不过等号右边的函数名只能在该函数内部调用使用,而他的作用域也只限于该函数内部。也就是说虽然在该函数内部覆盖了外部 var a = 1 的定义,但是在函数外部,a 依然为 1。

代码 3:

function a(x) {
    return x * 2;
}
var a;
alert(a);

这段代码也是一样是在测试我们对于 hoisting 的理解。

代码 4:

function b(x, y, a) {
    arguments[2] = 10;
    alert(a);
}
b(1, 2, 3);

arguments 表示我们传给函数的所有参数,是一个类似数组的数据结构,但并不是数组。和数组类似的是可以通过下标访问,下标从0开始,所以 arguments2 代表了传给该函数的第三个参数,也就是 a,所以 a 的值通过 arguments[2] = 10; 被重新赋值为 10。

代码 5:

function a() {
    alert(this);
}
a.call(null);

参照 [MDN] 中的关于 call 函数第一个参数的说明,我想大家就知道答案了:

The value of this provided for the call to fun. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode code, null and undefined will be replaced with the global object, and primitive values will be boxed.

更多参考

  1. JavaScript Guide: Values, variables, and literals
  2. JavaScript Guide: Function
  3. JavaScript Reference: Function and function scope