Zakas解答Baranovskiy的JavaScript小测试

Zakas 1/22在twitter上分享了Baranovskiy的一篇文章“So, you think you know JavaScript?”(你认为你够了解javascript吗)标题很叫板。结果5小段代码做的稀里哗啦。

今天Zakas专门撰文解答了这几道题(http://www.nczonline.net/blog/2010/01/26/answering-baranovskiys-javascript-quiz/)。不愧是大师,很深刻。

第1题: 是否真的理解声明变量
if (!(“a” in window)) {
var a = 1;
}
alert(a);

知识点:一是变量声明和初始化是分开的。二是Javascript引擎仅仅是把变量的声明提到当前scope的最前面解释。三是所有全局变量都是window对象的成员。所以这段代码实际是:
var a;
if (!(“a” in window)) {
a = 1;
}
alert(a);
答案就很清楚了-‘undefined’。

第2题:是否真的理解声明function
var a = 1,
b = function a(x) {
x && a(–x);
};
alert(a);
声明function只有两种一种是: function声明
function a (x) {
// do something.
}

另一种是: function表达式
var a = function (x) {
// do something.
}

function声明必须有方法名,而出现在表达式里的方法名都会被忽略。第二种function表达式就是一种赋值表达式,里面的方法名将被忽略。原文回复中提到的这篇文章(http://yura.thinkweb2.com/named-function-expressions/)写的很详细。

第3题:是否理解function声明的优先级
function a(x) {
return x * 2;
}
var a;
alert(a);
function声明会覆盖掉同名的变量声明,无论变量声明在前还是在后。但当变量赋值后,function就无效了。如:
var a = 1;
function a(x) {
return x * 2;
}
alert(a); //结果是 1

第4题:考是否理解参数对象
function b(x, y, a) {
arguments[2] = 10;
alert(a);
}
b(1, 2, 3);
答案是10。arguments相当于对应x, y, a建立的副本,Javascript引擎实现它们对应的值同步。所以arguments[2]的值变化了,a也随之变化。

第5题:是否真的理解call方法
function a() {
alert(this);
}
a.call(null);
ECMA262第3版标准里有明确说明:
“If thisArg is null or undefined, the called function is passed the global object as the this value. Otherwise, the called function is passed ToObject(thisArg) as the this value.”
可见,如果call的第一个参数是null或undefined,被调用的function将被传入全局对像作为this。全局对象就是window对象。所以,这道题的答案就很清楚了。

Zakas的原文更详细,我只是用更直白的话解读了一下。建议看原文。

Comments

  1. army8735 says:

    你效率真高,早上读完原文中午翻译就出来了。

    最近很流行翻译么?

  2. kejun says:

    @army8735 我基本上不翻译(英文不好;P),只是解读

  3. 马士华 says:

    作第一题时把脑中的SpiderMonkey中Conditionally defining a function当成了defining a variable.第二题:IE中是另一种解释.第三题:优先级以前还没有考察过,谢谢作者。

    给豆瓣挑个岔:首页登录框尽然不能用Tab键跳到“在这台电脑上记住我”这个复选框。打开页面一看没有tabIndex属性。

  4. kejun says:

    @马士华 谢谢反馈

  5. Guest says:

    var a = 1;
    function a(x) {
    return x * 2;
    }
    alert(a); //结果是 1
    这个你运行的结果是1?

  6. Miller says:

    第三题不应该用优先级来解释,只是变量与函数在解析过程中的不同造成的,具体可以参考http://varnow.org/?p=197 这里的解读

  7. kejun says:

    @Guest 是1. 奇怪的是用firebug的console运行不是1. 应该是firebug的问题

  8. kejun says:

    小马(@zhaozexin) 和 @josh_ma 推荐的这篇文章解释了firebug的问题。 http://perfectionkills.com/understanding-delete/#firebug_confusion “ All the text in console seems to be parsed and executed as Eval code”。eval等于新建了一个scope,和var声明不在同一个scope里解析,所以同名的后面覆盖前面的

  9. 马士华 says:

    @Miller 你的理解是对的,下面这个脚本更好的理解IE下的过程,注意IE和其它浏览器的区别。

    alert(a)
    var a = 1,b=function a(x) {
    return x * 2;
    }

    @kejun 这个问题困扰过我,所以才找到那片文章。

  10. jayli says:

    哈,换皮肤了

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">