你真的理解JavaScript了吗?

在著名前端架构师Dmitry Baranovskiy的博客里看到了一篇文章《So, you think you know JavaScript?》,很久以前的了。从5个小题目考查了js基础的知识点,大家有兴趣的可以先自己尝试做,不要借助浏览器调试,那样也没意思,拿出记事本,写出你自己的答案并尽量给出解释。好了,贴题目吧,先不要看答案哦。

第一题

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

第二题

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

第三题

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

第四题

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

第五题

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

-

-

-

-

-

-

-

-

-

-

-

-

-

-

-

答案

第一题:undefined

首先js里的变量,如果定义在全局范围内,这些变量都属于window上下文中的属性;其次,js引擎会提前扫描整个上下文,来查找var 变量定义,这个就是「预编译」,在本题中,var a 虽然是定义在 if 语句块内部,但实际上在代码运行前, var a 已经被 js引擎扫描到了,所以,这个 a 一定在运行时已经创建了,所以到了if判断语句的时候 a in window 肯定是 true,if语句块永远不会执行,所以a自然是undefined.

第二题:1

第二题有点儿诡异,我个人感觉这个 var b = function a() 这一句很奇葩,一般的程序员都不会这么写,那么这一题的意义是什么呢?我百思不得其解,后来想到了js 有一下几个变量定义的含义:变量声明(var a;),变量赋值(var a = 1),函数声明(function a(){....}),函数赋值(var a = function(){......}实际上跟变量赋值一样),大家暂且不要被那个 var b = function a()这一句给搞晕了,我把题目简化一下

var a = 1;

function a(){
o// blabla
}

alert(typeof a);

如果是这样的话,结果是 number。变量 a 被初始化而且赋值了,在这里 funtion a 不会覆盖这个 a ,因为这里仅仅是「声明」,而不是「赋值」。

第三题:function本身的字符串

这一题就跟第二题差不多啦,函数声明完毕后,js引擎发现当前上下文没有存在 a 变量的引用或者值,那么函数就会被创建了。

第四题:10

这一题比较简单,arguments 关键字是 js 这门语言灵活的体现,相信研究 js 的同学都不会对其陌生。这里引用 arguments 的第3个值,实际上就是 a ,你把它换掉了, a 自然也就换了。

第五题:[object Window]

这一题是考查了改变 js 函数运行时上下文的技术点,有 apply 和 call 两种形式,js 规范中有定义,只要 apply 和 call 的第一个参数是 null 或 undefined,那js都会认为当前的执行上下文是 window ,所以结果是这样就很好懂了。