下面这几道JavaScript题目大多来自于周五的一个小分享。都是很小的题目,但是很容易犯错。有一些是语言特性使然,有一些则是语言本身没有设计好而留下的陷阱。结果就是,遇到的人很容易陷进去骂娘,这些东西是略有些反直觉,感兴趣的不妨看看,平时我们还是尽量少些这样似是而非的代码。
1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
function
Container( properties ) {
var
objthis =
this
;
for
(
var
i
in
properties ) {
(
function
(){
var
t = properties[i];
objthis[
"get"
+ i ] =
function
() {
return
t;};
objthis[
"set"
+ i ] =
function
(val) {t = val;};
})();
}
}
var
prop = {Name :
"Jim"
, Age : 13};
var
con =
new
Container(prop);
console.log(con.getName());
con.setName(
"Lucy"
);
console.log(con.getName());
console.log(prop.Name);
|
这段代码会输出什么?前面两行分别是“Jim”和“Lucy”,这不会有问题;但是第三行应该输出的是“Jim”,但是有的人会误认为prop对象已被修改,故输出“Lucy”。其实在匿名函数中,properties[i]的值已经赋给了临时变量t,之后闭包对于外部变量的引用完全由t这个媒介来完成,因此prop传入以后并未发生任何属性的更改。
2.
1
2
3
4
5
|
function
a (x) {
return
x * 2;
}
var
a;
console.log(a);
|
这段代码中,其实var a并没有任何影响,输出的是a(x)这样的方法签名。
3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
c = 999;
var
c = 888;
console.log(
this
.c);
//①
function
b (x, y, c) {
c = 6;
arguments[2] = 10;
console.log(c);
//②
console.log(
this
.c);
//③
var
c = 6;
console.log(c);
//④
console.log(
this
.c);
//⑤
}
b(1, 2, 3, 4);
|
这道题是比较变态的。
- 第①处,this指的是window,在window下,c、this.c、var c在这里指的是同一个东西,看透这一点就好办了。打印的是888。
- 第②处,方法体中,参数c和arguments[2]指的是同一个地址,所以把后者赋为10的时候,打印的是10,不是6。
- 第③处,this指的是window,打印的是888。
- 第④处,打印的是6。
- 第⑤处,打印的是888。
4.
1
2
3
4
5
6
7
8
9
|
var
start =
new
Date();
setTimeout(
function
(){
var
end =
new
Date();
console.log(end - start);
},
1000
);
while
(
new
Date() - start < 2000);
|
JavaScript因为是单线程工作的,因此虽然毁掉函数设置了1000毫秒后执行,事实上在1000毫秒的时候根本得不到执行,等待到while循环执行完毕后(因此已经是2000毫秒以后了),才去执行,因此输出应该是一个大于2000的数字。
5.
1
2
3
|
(
function
(){
console.log(
typeof
arguments);
})();
|
很多人会说打印的是array,其实,arguments不是数组,打印的是object。
6.
1
2
|
function
a(){
return
a;}
console.log(
new
a()
instanceof
a);
|
应该打印的是false,其实原因很简单,new a()的时候,因为return语句,得到的不是a的实例,而是a本身,a instanceof a当然是false啦。
最后,还有一个小题目是关于Function Invocation Pattern的,我在这篇文章里有写到,就不单独贴出来了。
文章系本人原创,转载请保持完整性并注明出自《四火的唠叨》