关于 JavaScript 的36道题 [ JavaScript Puzzlers! ]

来源:互联网 发布:艾瑞数据网站排名 编辑:程序博客网 时间:2024/05/16 12:07

最近在微博上发现了一个网站 [ http://javascript-puzzlers.herokuapp.com/ ] 是关于 JavaScript 的36道题, 于是尝试自己做了下, 挺不错的, 在此总结下小小的收获. ^-^..

1.What is the result of this expression? (or multiple ones) ["1", "2", "3"].map(parseInt)
["1", "2", "3"][1, 2, 3][0, 1, 2]other

what you actually get is [1, NaN, NaN] because parseInt takes two parameters (val, radix) and map passes 3(element, index, array)

收获: parseInt( 字符串[, 字符串的进制] ), 其返回的数值是十进制的.
(1) 对于无法转换的值会返回 NaN.( 例如: parseInt('2', 2); 二进制状态下只能出现0/1, 2已超出其基数范围,返回 NaN )
(2) 不提供字符串的进制或者提供字符串的进制为 0, 若字符串以'0x'开头采用十六进制,若以'0'开头采用八进制,其他开头采用十进制 
 注; 若明确提供进制, 则此条不适用. 即 parseInt('0x7', 10); => 0 
(1)( parseInt 从头尽量匹配字符串,若第一个字符就不符合规则,像上面的例子,则输出NaN,若第一个字符符合,则一直匹配到结尾或不能匹配,例如此例中 'x' 不符合,则取0.同理 parseInt('012x7', 10) => parseInt('012', 10) => 12.像 000010010 的二进制会省略前面的 0 一样,十进制也一样,012 => 12)
(2)( parseInt 也会事先去掉字符串前后的空格(trim 一下) )
]

解析: 返回的新数组应该是[ parseInt('1', 0, ['1', '2', '3']),parseInt('2', 1, ['1', '2', '3']), parseInt('3', 2, ['1', '2', '3']) ], 对于 parseInt 来说第三个参数是用不上的, 因此依次是 [ 1, NaN, NaN ]

2.What is the result of this expression? (or multiple ones) [typeof null, null instanceof Object]
["object", false][null, false]["object", true]other

typeof will always return "object" for native non callable objects.


收获: typeof null -> 'object' ( 只是ECMA-262的规定 )
 关于 instanceof: object instanceof constructor 判断 constructor.prototype 是否在 object 的原型链上 ( 此处 null instanceof Object, Object.prototype,虽然所有对象的原型链顶端都是这个对象, 也可以推测类似 null, undefined, 12, true, 'abc'的简单类型没有原型链, 所以他们的 instanceof Object 都是 false )

3.What is the result of this expression? (or multiple ones) [ [3,2,1].reduce(Math.pow), [].reduce(Math.pow) ]
an error[9, 0][9, NaN][9, undefined]

Per spec: reduce on an empty array without an initial value throws TypeError

收获: Array.prototype.reduce(callback[,initialValue]); 将数组缩减为一个值,元素和之前的结果进行计算,计算返回值再和下一个元素进行计算.
      callback(previousValue, currentValue, currentIndex, array);
      previousValue,针对第一次调用,如果有initialValue则为initialValue,currentValue为数组的第一个元素,
                                  如果没有则为数组的第一个元素,currentValue为数组的第二个元素
     如果没有initaialValue, 且数组为空则抛出错误

4.What is the result of this expression? (or multiple ones) var val = 'smtg';console.log('Value is ' + (val === 'smtg') ? 'Something' : 'Nothing');
Value is SomethingValue is NothingNaNother

it actually prints 'Something' the + operator has higher precedence than the ternary one.

收获: + 优先级高于三元运算符, 'Value is true' ? 'Someting' : 'Nothing' => 'Something'

5.What is the result of this expression? (or multiple ones) var name = 'World!';(function () { if (typeof name === 'undefined') { var name = 'Jack'; console.log('Goodbye ' + name); } else { console.log('Hello ' + name); }})();
Goodbye JackHello JackHello undefinedHello World

The var declaration is hoisted to the function scope, but the initialization is not.


6.What is the result of this expression? (or multiple ones) var END = Math.pow(2, 53);var START = END - 100;var count = 0;for (var i = START; i <= END; i++) { count++;}console.log(count);
0100101other

it goes into an infinite loop, 2^53 is the highest possible number in javascript, and 2^53+1 gives 2^53, so i can never become larger than that.


收获; 2^53是JavaScript能表示的最大整数,当i === 2^53时之后再执行+1,i的值因为不能再大所以还是2^53满足等于的判断,无限循环.

7.What is the result of this expression? (or multiple ones) var ary = [0,1,2];ary[10] = 10;ary.filter(function(x) { return x === undefined;});
[undefined × 7][0, 1, 2, 10][][undefined]

Array.prototype.filter is not invoked for the missing elements.


收获: Array.prototype.filter(callback[,thisArg]) 产生一个新数组,原数组中的每一个元素经过callback的计算,函数返回true的进入新数组, 没有值的数组位置不调用callback,数组中没有调用callback的元素,不进入新数组.(因为if(i in arr)才进行操作). 
(1)callback(element,index,array)
(2)void 操作符: void操作符计算其后面的表达式,并且返回undefined.[The void operator evaluates the given expression and then returns undefined]

8.What is the result of this expression? (or multiple ones) var two = 0.2var one = 0.1var eight = 0.8var six = 0.6[two - one == one, eight - six == two]
[true, true][false, false][true, false]other

JavaScript does not have precision math, even though sometimes it works correctly.

9.What is the result of this expression? (or multiple ones) function showCase(value) { switch(value) { case 'A': console.log('Case A'); break; case 'B': console.log('Case B'); break; case undefined: console.log('undefined'); break; default: console.log('Do not know!'); }}showCase(new String('A'));
Case ACase BDo not know!undefined

switch uses === internally and new String(x) !== x

收获: switch进行的比较是===,不进行类型的隐式转换, new String('a') == 'a' -> true, new String('a') === 'a' -> false
new出来的是一个对象,而'a'是一个字符串 new String('a').toString() === 'a' -> true

10.What is the result of this expression? (or multiple ones) function showCase2(value) { switch(value) { case 'A': console.log('Case A'); break; case 'B': console.log('Case B'); break; case undefined: console.log('undefined'); break; default: console.log('Do not know!'); }}showCase2(String('A'));
Case ACase BDo not know!undefined

String(x) does not create an object but does return a string, i.e. typeof String(1) === "string"


收获: String()和字符串字面量相同

11.What is the result of this expression? (or multiple ones) function isOdd(num) { return num % 2 == 1;}function isEven(num) { return num % 2 == 0;}function isSane(num) { return isEven(num) || isOdd(num);}var values = [7, 4, '13', -9, Infinity];values.map(isSane);
[true, true, true, true, true][true, true, true, true, false][true, true, true, false, false][true, true, false, false, false]

Infinity % 2 gives NaN-9 % 2 gives -1 (modulo operator keeps sign so it's result is only reliable compared to 0)


收获: (1)负数取模,结果为其正数取模之后加负号,余数是0则依然为0.(2)当字符串参与运算时,如果是纯数字字符串则按数字计算(包括负数字符串'-5'%2 -> -1),与+不同只要运算符中有一个字符串(即使是纯数字字符串也按字符串计算)结果就是字符串

12.What is the result of this expression? (or multiple ones) parseInt(3, 8)parseInt(3, 2)parseInt(3, 0)
3, 3, 33, 3, NaN3, NaN, NaNother

3 doesn't exist in base 2, so obviously that's a NaN, but what about 0parseInt will consider a bogus radix and assume you meant 10, so it returns 3.


13.What is the result of this expression? (or multiple ones) Array.isArray( Array.prototype )
truefalseerrorother

Array.prototype is an Array. Go figure.


收获: Array.prototype 是数组,并且应该是带了很多字符串属性(比如Array.prototype.concat..)的数组.

14.What is the result of this expression? (or multiple ones) var a = [0];if ([0]) { console.log(a == true);} else { console.log("wut");}
truefalse"wut"other

[0] as a boolean is considered true. Alas, when using it in the comparisons it gets converted in a different way and all goes to hell.


收获: 比较的时候[0]竟然不是true...应该被认为是0了..[1] == true -> true..[0] == true -> false..还是不用为好.Boolean([0]) -> true.一定要用的话,比较前转换一下吧.

15.What is the result of this expression? (or multiple ones) []==[]
truefalseerrorother

== is the spawn of satan.


见解: 个人认为是两个对象进行比较,比较引用,因此不相等.

16.What is the result of this expression? (or multiple ones) '5' + 3 '5' - 3
"53", 28, 2errorother

Strings know about + and will use it, but they are ignorant of - so in that case the strings get converted to numbers.

收获: 同前面那个模运算(%)一样,字符串的纯数字在进行数字运算时会被当作数字,'+'除外.

17.What is the result of this expression? (or multiple ones) 1 + - + + + - + 1
21errorother

Great fun.

收获: 不要把表达式写的这么奇葩好不好..

18.What is the result of this expression? (or multiple ones) var ary = Array(3);ary[0]=2ary.map(function(elem) { return '1'; });
[2, 1, 1]["1", "1", "1"][2, "1", "1"]other

The result is ["1", undefined × 2], as map is only invoked for elements of the Array which have been initialized.


收获: map函数的实现中会构造和调用数组一样长度的数组作为返回,同时把原数组有值的位置进行计算放入新数组对应位置,原数组没有值的位置不进行操作.

19.What is the result of this expression? (or multiple ones) function sidEffecting(ary) { ary[0] = ary[2];}function bar(a,b,c) { c = 10 sidEffecting(arguments); return a + b + c;}bar(1,1,1)
312errorother

The result is 21, in javascript variables are tied to the arguments object so changing the variables changesarguments and changing arguments changes the local variables even when they are not in the same scope.


20.What is the result of this expression? (or multiple ones) var a = 111111111111111110000, b = 1111;a + b;
111111111111111111111111111111111111110000NaNInfinity

Lack of precision for numbers in JavaScript affects both small and big numbers.

疑问: 为何整数也缺少精度??

21.What is the result of this expression? (or multiple ones) var x = [].reverse;x();
[]undefinederrorwindow

[].reverse will return this and when invoked without an explicit receiver object it will default to the defaultthis AKA window


收获: 常规来说reverse函数有一个显式的接收者作为this, 函数返回这个this, 此处x的this是window, 全局对象

22.What is the result of this expression? (or multiple ones) Number.MIN_VALUE > 0
falsetrueerrorother

Number.MIN_VALUE is the smallest value bigger than zero, -Number.MAX_VALUE gets you a reference to something like the most negative number.


收获: MIN_VALUE是能表示的最小的大于0的值

23.What is the result of this expression? (or multiple ones) [1 < 2 < 3, 3 < 2 < 1]
[true, true][true, false]errorother

Implicit conversions at work. both true and false are greater than any number.


24.What is the result of this expression? (or multiple ones) // the most classic wtf 2 == [[[2]]]
truefalseundefinedother

both objects get converted to strings and in both cases the resulting string is "2"


收获: 将非Date类型对象转换为原始类型,优先尝试'valueOf'然后尝试'toString',还是没太搞明白, 为何都转换为字符串了?

25.What is the result of this expression? (or multiple ones) 3.toString()3..toString()3...toString()
"3", error, error"3", "3.0", errorerror, "3", errorother

3.x is a valid syntax to define "3" with a mantissa of xtoString is not a valid number, but the empty string is.


收获: 3.5.toString() -> '3.5'

26.What is the result of this expression? (or multiple ones) (function(){ var x = y = 1;})();console.log(y);console.log(x);
1, 1error, error1, errorother

y is an automatic global, not a function local one.


收获: 大意了, y没用var声明

27.What is the result of this expression? (or multiple ones) var a = /123/, b = /123/;a == ba === b
true, truetrue, falsefalse, falseother

Per spec Two regular expression literals in a program evaluate to regular expression objects that never compare as === to each other even if the two literals' contents are identical.



28.What is the result of this expression? (or multiple ones) var a = [1, 2, 3], b = [1, 2, 3], c = [1, 2, 4];a == b; a === b; a > c; a < c;
false, false, false, truefalse, false, false, falsetrue, true, false, trueother

Arrays are compared lexicographically with > and <, but not with == and ===


收获: 数组的大于小于是用字典序进行比较.

29.What is the result of this expression? (or multiple ones) var a = {}, b = Object.prototype;[a.prototype === b, Object.getPrototypeOf(a) === b]
[false, true][true, true][false, false]other

Functions have a prototype property but other objects don't so a.prototype is undefined
Every Object instead has an internal property accessible via Object.getPrototypeOf


30.What is the result of this expression? (or multiple ones) function f() {}var a = f.prototype, b = Object.getPrototypeOf(f);a === b
truefalsenullother

f.prototype is the object that will become the parent of any objects created with new f whileObject.getPrototypeOf returns the parent in the inheritance hierarchy.


31.What is the result of this expression? (or multiple ones) function foo() { }var oldName = foo.name;foo.name = "bar";[oldName, foo.name]
error["", ""]["foo", "foo"]["foo", "bar"]

name is a read only property. Why it doesn't throw an error when assigned, I do not know.


收获; 函数的name是只读属性,赋值无效,但不抛出异常.

32.What is the result of this expression? (or multiple ones) "1 2 3".replace(/\d/g, parseInt)
"1 2 3""0 1 2""NaN 2 3""1 NaN 3"

String.prototype.replace invokes the callback function with multiple arguments where the first is the match, then there is one argument for each capturing group, then there is the offset of the matched substring and finally the original string itself. so parseInt will be invoked with arguments 1, 02, 23, 4.

33.What is the result of this expression? (or multiple ones) function f() {}var parent = Object.getPrototypeOf(f); f.name // ? parent.name // ? typeof eval(f.name) // ? typeof eval(parent.name) // ?
"f", "Empty", "function", "function""f", undefined, "function", error"f", "Empty", "function", errorother

The function prototype object is defined somewhere, has a name, can be invoked, but it's not in the current scope.


收获: Function.prototype.name -> 'Empty'(长知识了..) 还有eval的参数是字符串类型的代码,上述代码相当于 typeof f -> 'function' 和 typeof Empty -> 报错

34.What is the result of this expression? (or multiple ones) var lowerCaseOnly = /^[a-z]+$/; [lowerCaseOnly.test(null), lowerCaseOnly.test()]
[true, false]error[true, true][false, true]

the argument is converted to a string with the abstract ToString operation, so it is "null" and "undefined".

收获: test函数参数自动转换为字符串!

35.What is the result of this expression? (or multiple ones) [,,,].join(", ")
", , , ""undefined, undefined, undefined, undefined"", , """

JavaScript allows a trailing comma when defining arrays, so that turns out to be an array of three undefined.


收获; 在join函数执行时, undefined和''空字符串效果类似

36.What is the result of this expression? (or multiple ones) var a = {class: "Animal", name: 'Fido'};a.class
"Animal"Objectan errorother

The answer is: it depends on the browser. class is a reserved word, but it is accepted as a property name by Chrome, Firefox and Opera. It will fail in IE. On the other hand, everybody will accept most other reserved words (intprivatethrows etc) as variable names too, while class is verboten.


收获: 不要用关键字做变量名产生歧义.

0 0
原创粉丝点击