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

前端 未结 5 1269
囚心锁ツ
囚心锁ツ 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

    This is more of a comment than an answer, but for some reason I can't comment on your question. I wanted to correct your JSFiddle code. However, I posted this on Hacker News and someone suggested that I repost it here.

    The problem in the JSFiddle code is that ({}) (opening braces inside of parentheses) is not the same as {} (opening braces as the start of a line of code). So when you type out({} + []) you are forcing the {} to be something which it is not when you type {} + []. This is part of the overall 'wat'-ness of Javascript.

    The basic idea was simple JavaScript wanted to allow both of these forms:

    if (u)
        v;
    
    if (x) {
        y;
        z;
    }
    

    To do so, two interpretations were made of the opening brace: 1. it is not required and 2. it can appear anywhere.

    This was a wrong move. Real code doesn't have an opening brace appearing in the middle of nowhere, and real code also tends to be more fragile when it uses the first form rather than the second. (About once every other month at my last job, I'd get called to a coworker's desk when their modifications to my code weren't working, and the problem was that they'd added a line to the "if" without adding curly braces. I eventually just adopted the habit that the curly braces are always required, even when you're only writing one line.)

    Fortunately in many cases eval() will replicate the full wat-ness of JavaScript. The JSFiddle code should read:

    function out(code) {
        function format(x) {
            return typeof x === "string" ?
                JSON.stringify(x) : x;
        }   
        document.writeln('>>> ' + code);
        document.writeln(format(eval(code)));
    }
    document.writeln("
    ");
    out('[] + []');
    out('[] + {}');
    out('{} + []');
    out('{} + {}');
    out('Array(16).join("wat" + 1)');
    out('Array(16).join("wat - 1")');
    out('Array(16).join("wat" - 1) + " Batman!"');
    document.writeln("
    ");

    [Also that is the first time I have written document.writeln in many many many years, and I feel a little dirty writing anything involving both document.writeln() and eval().]

提交回复
热议问题