JavaScript: Testen Sie Ihre Intuition


    Nach den Neujahrsferien schlug ich bereits vor, dass die Community ihre Gedanken durch Puzzlesituationen in JavaScript strecken sollte. Seit diesem Post ist viel Zeit vergangen, es gab viele andere Feiertage, daher schlage ich vor, über einen neuen Teil der Aufgaben nachzudenken.

    Ich werde die Antworten und meine eigene Version der Erklärung, warum dieses Verhalten logisch ist, wie beim letzten Mal unter dem Spoiler verstecken. Machen Sie sofort eine Reservierung, dass ich nicht vorgebe, die unerschütterliche Wahrheit meiner Fassungen zu sein, und ich werde sie gerne diskutieren. Eine ausgezeichnete russische Übersetzung der ECMAScript 5-Spezifikation kann Ihnen bei der Lösung dieses Problems helfen. Vielen Dank, iliakan !

    1. Das Hauptproblem des Lebens, des Universums und all das

    "3" -+-+-+ "1" + "1" / "3" * "6" + "2"
    

    Lösung
    "3" -+-+-+ "1" + "1" / "3" * "6" + "2" == "42"
    

    Wie wir bereits aus dem letzten Beitrag wissen, führt der Operator + entweder die Verkettung von Zeichenfolgen oder das Hinzufügen oder Reduzieren einer Zahl durch. Das heißt
    “3” + 2 == “32”
    

    nicht 5, wie du vielleicht denkst.

    Zusätzlich können Sie den unären Operator "+" oder "-" auf einen Ausdruck werfen, um dessen Vorzeichen zu ändern und die Dinge schöner und lesbarer zu machen.

    In Anbetracht all der oben genannten Punkte:
    + “1” === 1
    -+ “1” === -1
    +-+ “1” === -1
    …
    -+-+-+ === -1
    "3" -+-+-+ "1" === 2  //вычитание производится над числами
    


    Erinnern Sie sich als nächstes an die Priorität der Operationen: / * +
    “1”/”3” === 0.3333…
    “1” / ”3” * ”6” === 2
    2 + 2 === 4
    4 + “2” === “42”
    



    2. Maximalismus

    Math.max(3, 0); 
    Math.max(3, {});
    Math.max(3, []);
    Math.max(-1, [1]);
    Math.max(-1, [1, 4]);
    Math.max(3, true);
    Math.max(3, 'foo');
    Math.max(-1, null);
    Math.max(-1, undefined);
    

    Lösung
    Math.max(3, 0);           // 3
    

    Hier ist alles einfach.

    Math.max(3, {});          // NaN
    

    versuchen auszuführen toNumber für {}
    ausführen valueOf und prüfen , ob es primitiv ist - nein, dann
    ausführen toString erhalten „[das Objekt object]“ ; führe
    für den resultierenden String toNumber aus und erhalte NaN ;
    Wenn NaN empfangen wird, gibt Math.max () immer NaN zurück .

    Math.max(3, []);          // 3
    

    versuchen auszuführen toNumber auf []:
    ausführen valueOf und prüfen , ob es primitiv ist - nein, dann
    ausführen toString erhalten „“; führe
    für den resultierenden String toNumber aus und erhalte 0;
    3> 0

    Math.max(-1, [1]);     // 1
    

    wir werden versuchen, toNumber für [1]
    auszuführen : wir werden valueOf ausführen und prüfen, ob es primitiv ist - nein, dann werden wir toString
    ausführen und wir werden "1" erhalten; führe für den resultierenden String toNumber aus und erhalte 1; -1 <1



    Math.max(-1, [1, 4]);  // NaN
    

    versuche toNumber für [1,4]
    auszuführen : führe valueOf aus und überprüfe, ob dies primitiv ist - nein, dann
    führe toString aus und erhalte "1,4"; führe
    für den resultierenden String toNumber aus und erhalte NaN ;
    Wenn NaN empfangen wird, gibt Math.max () immer NaN zurück .

    Math.max(3, true);        // 3
    

    Versuche, toNumber für true
    auszuführen : Führe valueOf aus und überprüfe, ob dies primitiv ist - ja, dann
    toNumber(true) === 1
    

    3> 1

    Math.max(3, 'foo');       // NaN
    

    für 'foo' toNumber liefert NaN .
    Wenn NaN empfangen wird, gibt Math.max () immer NaN zurück .

    Math.max(-1, null);       // 0
    

    toNumber(null) === 0
    -1 < 0
    


    Math.max(-1, undefined);  // NaN
    

    toNumber(undefined) === NaN
    

    Wenn NaN empfangen wird, gibt Math.max () immer NaN zurück .


    3. Komma Leben

    [,,,].join()
    [,,,undefined].join()
    

    Versteckter Text
    [,,,].join()      // ",,"
    [,,,undefined].join()    // ",,,"
    

    Hier kann ich mich nur auf Flanagan beziehen. 7.1:
    „Wenn ein Array-Literal mehrere aufeinanderfolgende Kommas ohne Werte enthält, wird ein spärliches Array erstellt. Elemente, die solchen fehlenden Werten entsprechen, fehlen im Array, aber wenn auf sie zugegriffen wird, ist der Wert undefiniert. "
    " Die Syntax von Array-Literalen ermöglicht das Einfügen eines optionalen nachgestellten Kommas. "
    Warum ist mir das nicht klar? In den Kommentaren zum letzten Beitrag wurde dies als Feature vorgestellt. Meiner Meinung nach handelt es sich hierbei immer noch um eine Browser-Krücke aus Fehlern im Code.


    4. Schatzkarte

    Array(20).map(function(elem) { return 'a'; });
    

    Versteckter Text
    Array(20).map(function(elem) { return 'a'; }); // Array of undefined x 20
    

    Das Aufrufen des Array- Konstruktors mit einem Argument erstellt kein Array mit 20 Elementen, sondern ein Array mit einer Länge von 20. Die map- Methode erstellt zunächst ein leeres Array, dessen Länge der Länge des übertragenen Arrays entspricht, und ruft dann für jedes Element des übertragenen Arrays einen Rückruf auf. In unserem Fall hat das Array keine Elemente und die Methode gibt ein leeres Array mit der gleichen Länge wie das Original zurück.


    5. Finita la comedia

    isFinite(42);
    isFinite(1/0);
    isFinite(0/0);
    isFinite('42');
    isFinite('hi');
    isFinite();
    isFinite(undefined);
    isFinite(null);
    

    Versteckter Text
    isFinite(42); // true
    isFinite(1/0); // false
    isFinite(0/0); // NaN is not finite -> false
    isFinite('42'); // true
    isFinite('hi'); // false
    isFinite(); // false
    isFinite(undefined); // false
    isFinite(null); // true
    

    isFinite konvertiert das Argument in eine Zahl und gibt false zurück , wenn es NaN, + Infinity oder -Infinity ergibt . In allen anderen Fällen wahr . ToNumber von 'hi' gibt NaN zurück , undefined gibt NaN zurück und null gibt 0 zurück.



    6. Wahre Geschichte, Bruder

    'true' == true
    

    Versteckter Text
    'true' == true //false
    

    Der Gleichheitsoperator führt nacheinander dazu, dass die Zahlen zuerst wahr und dann 'wahr' sind. Es stellt sich heraus, dass NaN == 1 ist, was offensichtlich falsch ist.


    7. Nichts

    null == false
    !null
    

    Versteckter Text
    null == false // false
    !null // true
    

    Mit dem Casting von null auf bool ist alles klar. Beschäftigen wir uns mit dem Vergleich. Die Kombination von null und bool fällt nicht unter eine der Vergleichsoptionen in Abschnitt 11.9.3 der Spezifikation, und daher gibt der Vergleich false zurück .


    8. Unsicherheitsprüfung

    /^[a-z]{1,10}$/.test(null);
    /^[a-z]{1,10}$/.test(undefined);
    

    Versteckter Text
    /^[a-z]{1,10}$/.test(null);  //true
    /^[a-z]{1,10}$/.test(undefined);  //true
    

    Null und undefined werden wie folgt in den String umgewandelt: "null" und "undefined" - und solche Strings erfüllen den regulären Ausdruck. Und NaN wird übrigens auch zu "NaN".


    9. Negation von Null

     0 === -0
     1/0 === 1/-0
    

    Versteckter Text
     0 === -0        //true
     1/0 === 1/-0    //false
    

    Null ist eine negative Null, aber beim Teilen mit einem Vorzeichen wird das Vorzeichen berücksichtigt und es stellt sich heraus
    Infinity === -Infinity
    



    Für diejenigen Helden, die bis zum Ende gelesen haben, vielleicht das interessanteste Rätsel. Ich möchte die Erklärung nicht unter einem anderen Spoiler verbergen, daher rate ich Ihnen, devtools zu geben und dort zu überprüfen, nachdem Sie eine Antwort gegeben haben. Es ist wahrscheinlich, dass das Ergebnis Sie überraschen wird und Sie erneut darüber nachdenken möchten.
    10. Schrägstrich

    n = 1
    /1*"\/\//.test(n + '"//')
    n = 1;
    /1*"\/\//.test(n + '"//');
    

    Versteckter Text
    n = 1
    /1*"\/\//.test(n + '"//')  //NaN
    n = 1;
    /1*"\/\//.test(n + '"//');  //true
    

    Ein Schrägstrich kann in drei Fällen verwendet werden: regulärer Ausdruck, Division und Kommentar. Hier sehen wir auf den ersten Blick nur einen regulären Ausdruck. Tatsächlich führt der erste Schrägstrich ohne Semikolon eine Division durch. Daher wird zuerst eine Division durchgeführt, und dann wird das Ergebnis mit einer Zeichenfolge multipliziert. Der verbleibende Schwanz bleibt nur ein Kommentar. Die Linie, mit der wir mit der Zahl multiplizieren, wird nicht reduziert und NaN wird erhalten .

    Jetzt auch beliebt: