What is the explanation for these bizarre JavaScript behaviours mentioned in the 'Wat' talk for CodeMash 2012?

前端 未结 5 1277
囚心锁ツ
囚心锁ツ 2020-11-21 06:25

The \'Wat\' talk for CodeMash 2012 basically points out a few bizarre quirks with Ruby and JavaScript.

I have made a JSFiddle of the results at http://jsfid

5条回答
  •  忘了有多久
    2020-11-21 06:38

    We may refer to the specification and that's great and most accurate, but most of the cases can also be explained in a more comprehensible way with the following statements:

    • + and - operators work only with primitive values. More specifically +(addition) works with either strings or numbers, and +(unary) and -(subtraction and unary) works only with numbers.
    • All native functions or operators that expect primitive value as argument, will first convert that argument to desired primitive type. It is done with valueOf or toString, which are available on any object. That's the reason why such functions or operators don't throw errors when invoked on objects.

    So we may say that:

    • [] + [] is same as String([]) + String([]) which is same as '' + ''. I mentioned above that +(addition) is also valid for numbers, but there is no valid number representation of an array in JavaScript, so addition of strings is used instead.
    • [] + {} is same as String([]) + String({}) which is same as '' + '[object Object]'
    • {} + []. This one deserves more explanation (see Ventero answer). In that case, curly braces are treated not as an object but as an empty block, so it turns out to be same as +[]. Unary + works only with numbers, so the implementation tries to get a number out of []. First it tries valueOf which in the case of arrays returns the same object, so then it tries the last resort: conversion of a toString result to a number. We may write it as +Number(String([])) which is same as +Number('') which is same as +0.
    • Array(16).join("wat" - 1) subtraction - works only with numbers, so it's the same as: Array(16).join(Number("wat") - 1), as "wat" can't be converted to a valid number. We receive NaN, and any arithmetic operation on NaN results with NaN, so we have: Array(16).join(NaN).

提交回复
热议问题