最近在微博上发现了一个网站 [ http://javascript-puzzlers.herokuapp.com/ ] 是关于 JavaScript 的36道题, 于是尝试自己做了下, 挺不错的, 在此总结下小小的收获. ^-^..
["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)
(1) 对于无法转换的值会返回 NaN.( 例如: parseInt('2', 2); 二进制状态下只能出现0/1, 2已超出其基数范围,返回 NaN )
(2) 不提供字符串的进制或者提供字符串的进制为 0, 若字符串以'0x'开头采用十六进制,若以'0'开头采用八进制,其他开头采用十进制
[typeof null, null instanceof Object]["object",
false][null,
false]["object",
true]other
typeof will always return "object" for native non callable objects.
[ [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
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.
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.
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.
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.
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.
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
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"
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)
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 0? parseInt will consider a bogus radix and assume you meant 10, so it returns 3.
Array.isArray( Array.prototype )truefalseerrorother
Array.prototype is an Array. Go figure.
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.
[]==[]truefalseerrorother
== is the spawn of satan.
'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.
1 + - + + + - + 121errorother
Great fun.
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.
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.
var a = 111111111111111110000, b = 1111;a + b;111111111111111111111111111111111111110000NaNInfinity
Lack of precision for numbers in JavaScript affects both small and big numbers.
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
Number.MIN_VALUE > 0falsetrueerrorother
Number.MIN_VALUE is the smallest value bigger than zero, -Number.MAX_VALUE gets you a reference to something like the most negative number.
[1 < 2 < 3, 3 < 2 < 1][true,
true][true,
false]errorother
Implicit conversions at work. both true and false are greater than any number.
// the most classic wtf 2 == [[[2]]]truefalseundefinedother
both objects get converted to strings and in both cases the resulting string is "2"
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 x, toString is not a valid number, but the empty string is.
(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.
var a = /123/, b = /123/;a == ba === btrue,
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.
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 ===
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
function f() {}var a = f.prototype, b = Object.getPrototypeOf(f);a === btruefalsenullother
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.
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.
"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, 0, 2, 2, 3, 4.
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.
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".
[,,,].join(", ")",
, , ""undefined,
undefined, undefined, undefined"",
, """
JavaScript allows a trailing comma when defining arrays, so that turns out to be an array of three undefined.
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 (int, private, throws etc)
as variable names too, while class is verboten.
391

被折叠的 条评论
为什么被折叠?



