英文原文地址:http://dmitry.baranovskiy.com/post/91403200
其中有五段小代码,用来测试是否理解 JavaScript 的核心(core),闭包(closures)和作用域(scopes)。先尝试回答每段代码中alert语句的结果,然后再作实践检查。
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);
解析参考:http://bbs.csdn.net/topics/390300541
首先会解析所有函数,其次是var声明的变量,但是不会赋值。因为JavaScript没有块(block)的概念。像for(var i in array)这里的i依然是全局变量,这点非常的不同于Java。因此,这几行的代码执行顺序是:
第二题解析:
我们可以用多个逗号将变量分开定义,只用一个var。另外函数表达式类似于局部变量,不会被全局作用域中访问到。执行步骤:
JavaScript永远是先解析声明式函数,再解析变量。所以,它的执行顺序为:
在函数内部可以引用一个对象,它是arguments类似数组,但不是数组。它代表了函数实际接收参数的集合。可以通过下标对相应参数进行访问。如果修改此对象某些属性,如arguments[index],则被传进来的第index(如果有的话,下标从0开始)变量的值也会被修改。它的执行顺序为:
注意1:形参优先级高于arguments
function fn(arguments){ alert(arguments); } fn('hello'); // -> "hello"
注意2:在JavaScript中如果定义了2个或2个以上的相同名字的函数,则只有最后定义的函数才有效。
function b(x, y, a) { arguments[2] = 10; alert(x); } function b(x, y, a, b) { arguments[2] = 10; alert(y); } b(1, 2, 3); // -> 2
call方法接受多个参数,其作用是借用别人的方法当作自己的方法。这样能保证执行的时候this能够指向自己。
call方法的第二个参数到最后一个参数是传给借用过来函数的。第一个参数是借用的对象,如果这个对象为空,那么将会作为全局window对象调用。即函数中的this指向window,结果为[object Window]。
经验:a()/a.call()/a.call(null)无区别。