2016-06-29 8 views
2

Ok Jungs. Ich habe diesen grundlegenden Code, der eine jQuery-esque Funktion zurückgibt, die Q genannt wird.Funktionsaufruf - dies == Fenster und nicht undefiniert

q=new function(){ 
    var u,q; 
    q=function Q(slf){ 
     console.log('slf ⇒',slf); 
     ex=q_ex.call(slf); 
     console.log('ex ⇒',ex); 
    }; 
    return q; 
    function q_ex(){ 
     console.log('this ⇒',this); 
     return (this!==u && this!==null); 
    }; 
}; 

Wenn ich q(); anrufen sollte. Die sich ergebende Konsolenanzeige wäre:

slf  ⇒ undefined 
this ⇒ Window {external: Object, chrome: Object, document: document, speechSynthesis: SpeechSynthesis, caches: CacheStorage…} 
ex  ⇒ true 

Nun ist die kluge unter euch werden erkennen, dass ich this erfordern undefined und nicht Window zu sein!

Fehle ich etwas hier, oder tut this Standard Window, wenn er den Wert null oder undefined hat?

+1

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call#Parameters – undefined

+2

Von dieser Referenz "*, wenn die Methode eine Funktion im nicht strikten Modus ist code, null und undefined werden durch das globale Objekt ersetzt. * " –

+2

Verwenden Sie den strikten Modus und Sie erhalten wie erwartet" undefined ". – Bergi

Antwort

1

konnte mir etwas zum Laufen bringen, indem Sie einige Codes um zu ändern:

var q = (function() { 
 
    'use strict'; 
 
    
 
    var u; 
 
    
 
    function q_ex() { 
 
    console.log('this ⇒',this); 
 
    return (this!==u && this!==null); 
 
    } 
 
    
 
    return function Q(slf) { 
 
    console.log('slf ⇒',slf); 
 
    var ex = q_ex.call(slf); 
 
    console.log('ex ⇒',ex); 
 
    } 
 
})(); 
 

 
q({ foo: 'bar' }); 
 
q();

+0

schlechtes Beispiel von dem, was ich brauche, aber abgeholt auf 'Use strict', Prost. – LostInCyberSpace

1

Ja, this zu Fenstern auf dem Standard neigt, also warum mit new gefährlich ist. Die Antwort auf, warum Sie erhalten undefined beim Drucken von llf braucht ein bisschen mehr Code-Beispiele, um richtig zu erklären, werde ich das tun, wenn ich nach Hause komme, wie ich auf meinem Telefon im Moment bin

Edits: Zuerst habe ich gemacht eine Reihe von Kommentaren zu Ihrem ursprünglichen Code einige Probleme zu markieren fand ich

// Dont use new, its not needed here, use closures 
// Also q is not declared here so it will become a global variable, bad bad bad 
q=new function(){ 
    // Both declarations are unneeded as you can just return q straight away 
    // and u never gets a value assigned to it so why declare it? 
    // If you want to compare with undefined then just write this !== undefined 
    // Also, refrain from using the same names in nested structures if you value your sanity 
    var u,q; 

    // Use either q = function(...){...} or function Q(...){...} 
    q=function Q(slf){ 
     console.log('slf ⇒',slf); 
     // ex is not declared with var so this will create a global variable, bad bad bad 
     ex=q_ex.call(slf); 
     console.log('ex ⇒',ex); 
    }; 

    // No need to write the function and then return it. 
    // Use return(function(...){...}) instead. 
    return q; 

    // Just a personal preference but I'd put this before the return 
    // statement to make it more readable and also use q_ex = function(...){...} 
    function q_ex(){ 
     console.log('this ⇒',this); 
     return (this!==u && this!==null); 
    }; 
}; 

Unten ist, wie ich es

var q = (function(){ // Closure 
    var q_ex; // Declarations 

    q_ex = function() { // Internal function 
    console.log('this ⇒', this); 
    return (this!==undefined && this!==null); 
    }; 

    return(function(slf) { // Returned function 
    console.log('slf ⇒', slf); 
    var ex = q_ex.call(slf); 
    console.log('ex ⇒', ex); 
    }); 
})(); // Call in the end to get returned function 

q() // Returns the same as yours did 
q(5) // A numeric object with the value of 5 is now set as 'this' 

die Art und Weise Sie Ihr schrieb schreiben würde scheint wie meine das gleiche genau zu arbeiten, aber Ich kann es nicht genau verstehen. Könnte nur sein, dass ich zu tief in der Verschlussreligion bin.

Wie auch immer, das Problem, das Sie hatten, rührt von der Tatsache her, dass Sie q() ohne Parameter ausführen. Wenn Sie q(5) ausgeführt haben, sehen Sie, dass this 5 wird. Dies liegt daran, dass der this-Parameter nicht angegeben wird, wenn er Window lautet. Dies ist der Grund, warum new oft gefährlich ist. Angenommen, Sie haben ein Objekt geschrieben, das this darin verwendet, um Werte zu speichern, und daher mit new erstellt werden muss. Nun, wenn jemand es erstellt und vergessen hat, new zu verwenden, verschmutzen Sie den globalen Namespace, indem Sie alle Ihre Variablen an das Window Objekt anhängen (Window === global im Browser). Ein guter Weg um dieses Risiko ist es, Ihre Objekte mit Verschlüssen zu schreiben, auf diese Weise, wie auch immer sie erstellt werden, sie arbeiten immer noch die gleichen. Sie können immer noch auf die Variablen zugreifen, die Sie von Ihrer Closing-Funktion verwenden möchten, indem Sie einfach ihren Namen verwenden oder wenn Sie sie gruppieren möchten, erstellen Sie einfach ein einzelnes "Master" -Objekt in Ihrer Closing-Funktion und fügen Sie alles hinzu.

Auch im Wesentlichen verbietet 'use strict' einige schlechte Praktiken. Lesen Sie es auf und verwenden Sie es, macht das Leben leichter. Verwenden Sie auch oder einen anderen JavaScript-Qualitätsprüfer, um den Code sauber zu halten.

Hoffnung, die geholfen hat.

+0

Ich lese durch den Mozilla-Link oben und die strengen/nicht-strikten Modi, um zu verstehen, aber Beispiele immer willkommen! – LostInCyberSpace

+0

Ich erweiterte meine Antwort – Taavi

0

Ok Jungs für jeden, der zuschaut, ich habe meine Antwort gefunden.Aber zuerst werde ich ein wenig auf dem Code klären ...


q=new function(){ 

Der Grund für die Verwendung new function ist, dass ich noch nie wirklich gebraucht/praktiziert mit self-executing - anonymen Funktionen vor und das war die Nur so wusste ich wie!


q(x) === function Q(x){...} 

q ist gezielt global!


u ist eine Abkürzung für undefined, var u === var u=undefined ..


Es ist wahr, ich this !== undefined schreiben kann, aber q_ex() verwendet werden, in Zukunft für mehrere Objekttypen, von Strings in Zahlen usw. ..


Diese Ebene der 'gleichen Namen Variablen' ist durchaus akzeptabel für seinen Zweck!


q=function Q(slf){ 

Der Grund für die Funktion Namensgebung ist rein astetic, und einmal im Allgemeinen entfernt Codierung getestet wird.


ex=q_ex.call(slf); 
// ex is not declared with var so this will create a global variable, bad bad bad 

Gut erkannt! Obwohl dies eine etwas vereinfachte Version des Codes ist, der das Problem verursacht, muss ex hier nicht erklärt werden, damit das Problem auftritt.


Eine letzte Sache ... Ich verstehe, scheint es keinen Grund für das äußere Gehäuse des ‚Q‘ Funktion zu sein, aber wenn man genauer hinsehen ... Meine einzige globale Variable ist ‚q‘! Wenn nicht für das äußere Gehäuse: u, q, q_ex und irgendein zukünftiges Objekt wäre global und dies ist NICHT das Erforderliche.


Ok dann, meine Antwort ...

'use strict'; 

Function.prototype.call
Strict mode


Die Lösung für mein Leiden ...

var q=(function(){ 
    var u,q; 
    q=function Q(slf){ 
     console.log('slf ⇒',slf); 
     var ex=q_ex.call(slf); 
     console.log('ex ⇒',ex); 
    }; 
    return q; 
    function q_ex(){ 
     'use strict'; 
     console.log('this ⇒',this); 
     return (this!==u && this!==null); 
    }; 
})(); 

q(); 

slf  ⇒ undefined 
this ⇒ undefined 
ex  ⇒ false 

Vielen Dank für Ihre Hilfe Jungs, ich kann jetzt mit dem größeren Bild weitermachen!

Ich werde versuchen, mich von der Verwendung new function zu entfernen und es durch (function(){})() ersetzen.

Hoffe, das hilft.

Verwandte Themen