本文详细解析了 JavaScript Perfection Kills 网站的经典测试题,涵盖 arguments 对象、函数声明提升、this 指向、变量作用域及 delete 操作符等核心知识点。通过逐题分析代码执行逻辑与浏览器差异,帮助开发者深入理解 JavaScript 引擎运行机制,避免常见陷阱。
JavaScript Perfection Kills 测试题解析与答案详解
以下是来自 Perfection Kills 网站的 JavaScript 测试题,官方地址为 http://perfectionkills.com/javascript-quiz/。
代码部分如下:
1.
(function(){
return typeof arguments;
})();
“object”
“array”
“arguments”
“undefined”
2.
var f = function g(){ return 23; };
typeof g();
“number”
“undefined”
“function”
Error
3.
(function(x){
delete x;
return x;
})(1);
1
null
undefined
Error
4.
var y = 1, x = y = typeof x;
x;
1
“number”
undefined
“undefined”
5.
(function f(f){
return typeof f();
})(function(){ return 1; });
“number”
“undefined”
“function”
Error
6.
var foo = {
bar: function() { return this.baz; },
baz: 1
};
(function(){
return typeof arguments[0]();
})(foo.bar);
“undefined”
“object”
“number”
“function”
7.
var foo = {
bar: function(){ return this.baz; },
baz: 1
}
typeof (f = foo.bar)();
“undefined”
“object”
“number”
“function”
8.
var f = (function f(){ return "1"; }, function g(){ return 2; })();
typeof f;
“string”
“number”
“function”
“undefined”
9.
var x = 1;
if (function f(){})
x += typeof f;
}
x;
1
“1function”
“1undefined”
NaN
10.
var x = [typeof x, typeof y][1];
typeof typeof x;
“number”
“string”
“undefined”
“object”
11.
(function(foo){
return typeof foo.bar;
})({ foo: { bar: 1 } });
“undefined”
“object”
“number”
Error
12.
(function f(){
function f(){ return 1; }
return f();
function f(){ return 2; }
})();
Error (e.g. “Too much recursion”)
undefined
13.
function f(){ return f; }
new f() instanceof f;
true
false
14.
with (function(x, undefined){}) length;
undefined
Error 以下是个人对题目的解答与分析:
代码如下:
// Q1
(function(){
return typeof arguments; // 这里显然返回 "object"
})();
// Q2
var f = function g(){ return 23; };
typeof g(); // 在 IE 浏览器中返回 "number",但在 Firefox 中会报错(g 未定义)
// Q3
(function(x){
delete x; // 局部变量无法被 delete 删除
return x; // 因此返回 1
})(1);
/*
补充知识:
delete 操作符与变量的关系如下:
1、对象预定义的属性无法被 delete;2、通过 prototype 定义的属性也无法被 delete
// 关于第 2 点,可以理解为只能删除动态附加给对象实例的属性吗?
3、var 定义的变量(局部变量)无法被 delete;4、function 定义的变量及参数(相当于局部变量)也无法被删除。
关于 delete 的详细介绍,可参考:http://tech.idv2.com/2008/01/09/javascript-variables-and-delete-operator/
*/
// Q4
var y = 1, x = y = typeof x;
x; // 显然 x 应该是 undefined
// Q5
(function f(f){
return typeof f(); // 这里的 f 指的是传入的匿名函数,因此结果应该是 "number" (即 1)
})(function(){ return 1; });
// Q6
var foo = {
bar: function() { return this.baz; },
// 调用后,this 指向 bar,而 bar 没有 baz 属性,因此是 undefined
baz: 1
};
(function(){
return typeof arguments[0](); // arguments[0] 是 foo.bar
})(foo.bar);
// Q7
var foo = {
bar: function(){ return this.baz; }, // 同第 6 题
baz: 1
}
typeof (f = foo.bar)();
// Q8
var f = (function f(){ return "1"; }, function g(){ return 2; })();
// js 的逗号操作符,调用的是第二个函数,因此返回 "number"
typeof f;
// Q9
var x = 1;
if (function f(){})
x += typeof f; // IE 下是 1function,FF 下是 1undefined
}
x;
// Q10
var x = [typeof x, typeof y][1]; // x = "undefined"
typeof typeof x; // x 是字符串,因此应该是 "string"
// Q11
(function(foo){
return typeof foo.bar;
// 这是一道非常隐蔽的题目,参数 foo 指向传入的 JSON 对象,而该对象有一个 foo 属性。
// 因此,如果是 typeof foo.foo.bar 的话结果就是 "number"
// 但参数 foo 本身没有 bar 属性,因此结果是 "undefined"
})({ foo: { bar: 1 } });
// Q12
(function f(){
function f(){ return 1; }
return f(); // 函数定义,后者覆盖前者,因此结果是 2
function f(){ return 2; }
})();
// Q13
function f(){ return f; }
new f() instanceof f;
// new f() 实际上与 f 是同一个东西,都是 function,因此两者相等,结果是 false
// 如果 function f(){return 1;}, 则返回的是 object
// Q14
with (function(x, undefined){}) length;
// 这样写就明白了 with(function(x,undefined){}){length;}
// 而 length 指的是函数的形参个数,因此是 2