Kann ich Variablen auf undefiniert setzen oder undefiniert als Argument übergeben?

304

Ich bin etwas verwirrt über JavaScript undefinedund nullWerte.

Was macht if (!testvar)eigentlich? Testet es für undefinedund nulloder nur undefined?

Kann ich eine einmal definierte Variable wieder undefinedlöschen (daher die Variable löschen)?

Kann ich undefinedals Parameter übergeben? Z.B:

function test(var1, var2, var3) {

}

test("value1", undefined, "value2");
AJ.
quelle
Antwort
Premraj

Antworten:

514

Ich bin ein bisschen verwirrt über Javascript undefined & null.

Sei nicht verwirrt null. Es ist im Allgemeinen sinnvoll und verhält sich ähnlich wie die Konzepte anderer Skriptsprachen für die Out-of-Band-Objekte 'null', 'nil' oder 'None'.

undefinedAuf der anderen Seite ist eine seltsame JavaScript-Eigenart. Es ist ein Singleton-Objekt, das Out-of-Band-Werte darstellt, im Wesentlichen ein zweites ähnliches, aber unterschiedliches Objekt null. Es kommt auf:

  1. Wenn Sie eine Funktion mit weniger Argumenten als der Argumentliste in den functionAnweisungslisten aufrufen, werden die nicht übergebenen Argumente auf gesetzt undefined. Sie können dies testen mit z.

    function dosomething(arg1, arg2) {
        if (arg2===undefined)
        arg2= DEFAULT_VALUE_FOR_ARG2;
        ...
    }

    Mit dieser Methode können Sie den Unterschied zwischen dosomething(1)und nicht erkennen dosomething(1, undefined). arg2wird in beiden der gleiche Wert sein. Wenn Sie den Unterschied erkennen müssen, können Sie sich das ansehen arguments.length, aber solche optionalen Argumente sind im Allgemeinen nicht gut lesbar.

  2. Wenn eine Funktion no hat return value;, wird sie zurückgegeben undefined. Es ist im Allgemeinen nicht erforderlich, ein solches Rückgabeergebnis zu verwenden.

  3. Wenn Sie eine Variable deklarieren, indem Sie eine var aAnweisung in einem Block haben, ihr jedoch noch keinen Wert zugewiesen haben, ist dies der Fall undefined. Auch hier sollten Sie sich nie wirklich darauf verlassen müssen.

  4. Der gruselige typeofOperator kehrt zurück, 'undefined'wenn sein Operand eine einfache Variable ist, die nicht existiert, anstatt einen Fehler auszulösen, wie es normalerweise der Fall wäre, wenn Sie versuchen würden, darauf zu verweisen. (Sie können ihm auch eine einfache Variable in Klammern geben, aber keinen vollständigen Ausdruck mit einer nicht vorhandenen Variablen.) Auch dafür ist es nicht sehr nützlich.

  5. Dies ist der umstrittene. Wenn Sie auf eine Eigenschaft eines Objekts zugreifen, die nicht vorhanden ist, wird nicht wie in jeder anderen Sprache sofort ein Fehler angezeigt. Stattdessen erhalten Sie ein undefinedObjekt. (Und wenn Sie dann versuchen, dieses undefinedObjekt später im Skript zu verwenden, wird es auf eine seltsame Weise schief gehen, die viel schwieriger zu finden ist, als wenn JavaScript gerade sofort einen Fehler ausgelöst hätte.)

    Dies wird häufig verwendet, um das Vorhandensein von Eigenschaften zu überprüfen:

    if (o.prop!==undefined) // or often as truthiness test, if (o.prop)
       ...do something...

    Da Sie jedoch undefinedwie jeden anderen Wert zuweisen können:

    o.prop= undefined;

    das erkennt eigentlich nicht, ob die Immobilie dort zuverlässig ist. Verwenden Sie besser den inOperator, der nicht in der ursprünglichen Netscape-Version von JavaScript enthalten war, jetzt aber überall verfügbar ist:

    if ('prop' in o)
        ...

Zusammenfassend undefinedist ein JavaScript-spezifisches Durcheinander, das alle verwirrt. Abgesehen von optionalen Funktionsargumenten, bei denen JS keinen anderen eleganteren Mechanismus hat, undefinedsollten diese vermieden werden. Es hätte niemals Teil der Sprache sein dürfen; nullhätte für (2) und (3) gut funktioniert, und (4) ist eine Fehlfunktion, die nur existiert, weil JavaScript am Anfang keine Ausnahmen hatte.

was macht if (!testvar)eigentlich Testet es auf undefiniert und null oder nur undefiniert?

Eine solche ‚Truthiness‘ Test prüft , gegen false, undefined, null, 0, NaNund leere Strings. Aber in diesem Fall geht es wirklich undefineddarum. IMO, es sollte expliziter sein und sagen if (testvar!==undefined).

Sobald eine Variable definiert ist, kann ich sie wieder auf undefiniert löschen (daher die Variable löschen).

Sie können es sicherlich zuweisen undefined, aber das wird die Variable nicht löschen. Nur der delete object.propertyBediener entfernt wirklich Dinge.

deleteist eigentlich eher für Eigenschaften als für Variablen als solche gedacht. Mit Browsern können Sie direkt davonkommen delete variable, aber es ist keine gute Idee und funktioniert nicht im strengen Modus von ECMAScript Fifth Edition. Wenn Sie einen Verweis auf etwas freigeben möchten, damit es durch Müll gesammelt werden kann, ist es üblicher zu sagen variable= null.

Kann ich undefined als Parameter übergeben?

Ja.

Bobince
quelle
10
Was für eine fantastische Antwort. Ich habe gerade den JavaScript-Test nicht bestanden: perfektionkills.com/javascript-quiz Später werde ich Ihre Antwort erneut lesen und den Test erneut versuchen!
Skilldrick
1
fest, ta. (Ich mache mir keine allzu großen Sorgen um die Neuzuweisung, da es so viele Dinge gibt, die ein Skript neu definieren könnte, um alles durcheinander zu bringen, dass der allgemeine Fall nicht zu lösen ist.)
Bobince
2
@ Bobince undefinedist ein Singleton-Objekt? Was meinst du? Es ist ein primitiver Wert und kein Objekt.
Šime Vidas
2
@Hortitude: Das ist Punkt (4). Ich würde im Allgemeinen nicht typeof foo=='undefined'; Es wird in der Regel für (4a) globales Schnüffeln verwendet. In diesem Fall würde ich es vorziehen, explizit zu sein und zu sagen 'foo' in window, oder (4b) gegen den undefinedWert selbst zu testen. In diesem Fall würde ich es vorziehen, lesbar zu sein und zu sagen foo===undefined. Theoretisch könnte das Testen typeofgegen 'undefined'einen Anwendungsfall haben, den andere Konstrukte nicht bieten könnten: das Schnüffeln auf die Existenz lokaler Variablen. In Wirklichkeit wissen Sie jedoch so ziemlich immer, welche Variablen als lokal deklariert sind.
Bobince
4
Eine Einschränkung mit # 2, normalerweise eine Funktion ohne returnAnweisung undefined, wird zurückgegeben. Wenn die Funktion jedoch ein Konstruktor ist (der vom newOperator aufgerufen wird ), wird das neue Objekt (der Wert thisinnerhalb des Konstruktors) zurückgegeben, obwohl keine returnAnweisung vorhanden ist. console.log((function (){}()));kehrt zurück undefined. console.log((new function (){}()));gibt ein Objekt zurück.
Nutzloser Code
18

Sie können (sollten nicht?) Nichts als undefiniert definieren, da die Variable nicht mehr undefiniert wäre - Sie haben sie nur für etwas definiert .

Sie können (sollten nicht?) Nicht undefinedan eine Funktion übergeben. Wenn Sie einen leeren Wert übergeben möchten, verwenden Sie nullstattdessen.

Die Anweisung if(!testvar)prüft auf boolesche True / False-Werte. In dieser Anweisung wird geprüft, ob eine testvarBewertung vorliegt false. Per Definition nullund undefinedsollte weder als ausgewertet trueoder falseaber JavaScript auswertet nullwie falseund gibt einen Fehler , wenn Sie versuchen , eine nicht definierte Variable zu bewerten.

Verwenden Sie diese, um ordnungsgemäß auf undefinedoder zu testen null:

if(typeof(testvar) === "undefined") { ... }

if(testvar === null) { ... }
Tatu Ulmanen
quelle
1
Das Triple-Equals prüft auch den Typ, sodass kein Typzwang durchgeführt wird. Douglas Crockford rät von der Verwendung der Typ-Coercing-Operatoren ( ==und !=) ab.
Skilldrick
3
Sie können etwas als undefiniert definieren. var a= undefined. Sie können passieren fn(undefined). Wenn Sie den Unterschied zwischen einer undefinierten Eigenschaft peines Objekts ound einer Eigenschaft p, die definiert und festgelegt wurde undefined, ermitteln möchten , müssen Sie den 'p' in oOperator verwenden.
Bobince
1
Gibt es einen Grund, warum man nicht testvar === undefinedeher auf die komplizierteren testen sollte typeof(testvar) === "undefined"?
Ddaa
4
Es ist ein weiterer guter Grund , eine für die Verwendung von typeofTest für nicht definierte Variablen: Im Gegensatz zu null, undefinedist einfach eine Eigenschaft des globalen Objekts und selbst neu definiert werden kann. Es braucht nur einen bestimmten Codierungsstil und ein fehlendes Gleichheitszeichen und undefinedwird stillschweigend geändert:if (undefined = someVar) {...}
Tim Down
1
@IanGrainger: ECMAScript 5 (in aktuellen Versionen aller Browser implementiert) behebt dies meistens, indem undefinedeine unveränderliche Eigenschaft des globalen Objekts erstellt wird, sodass es sicherer ist als früher. Es ist jedoch weiterhin möglich, eine veränderbare Variable zu definieren, die undefinedinnerhalb einer Funktion aufgerufen wird , sodass das Problem nicht vollständig behoben ist.
Tim Down
13

Der grundlegende Unterschied ist , dass undefinedund nullunterschiedliche Konzepte darstellen.

Wenn nur nullverfügbar wäre, könnten Sie nicht feststellen, ob nullabsichtlich als Wert festgelegt wurde oder ob der Wert noch nicht festgelegt wurde, es sei denn, Sie haben eine umständliche Fehlererkennung verwendet: z

var a;

a == null; // This is true
a == undefined; // This is true;
a === undefined; // This is true;

Wenn Sie den Wert jedoch absichtlich auf festlegen null, undefinedschlägt die strikte Gleichheit mit fehl, wodurch Sie zwischen nullund undefinedWerten unterscheiden können:

var b = null;
b == null; // This is true
b == undefined; // This is true;
b === undefined; // This is false;

Schauen Sie sich die Referenz hier an, anstatt sich darauf zu verlassen, dass Leute abweisend Junk sagen wie "Zusammenfassend ist undefiniert ein JavaScript-spezifisches Durcheinander, das alle verwirrt". Nur weil Sie verwirrt sind, heißt das nicht, dass es ein Chaos ist.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined

Dieses Verhalten ist auch nicht spezifisch für JavaScript und es vervollständigt das verallgemeinerte Konzept , dass ein logisches Ergebnis sein kann true, falseunbekannt ( null), keinen Wert (undefined ) oder etwas schief gelaufen ist ( error).

http://en.wikipedia.org/wiki/Undefined_value

Todd
quelle
Und nullhätte trotzdem gut funktioniert. a == nullliegt truedaran, dass Javascript Typ Zwang.
sleepwalkerfx
11

Der beste Weg, um nach Nullwerten zu suchen, ist

if ( testVar !== null )
{
    // do action here
}

und für undefiniert

if ( testVar !== undefined )
{
    // do action here
}

Sie können eine Avariable mit undefined zuweisen.

testVar = undefined;
//typeof(testVar) will be equal to undefined.
rahul
quelle
1
Der beste Weg, um nach Nullwerten zu suchen, ist zu verwenden !==, nicht!=
MBO
6

Ja, Sie können, weil nicht definiert ist definiert als nicht definiert.

console.log(
   /*global.*/undefined === window['undefined'] &&
   /*global.*/undefined === (function(){})() &&
   window['undefined']  === (function(){})()
) //true

dein Fall:

test("value1", undefined, "value2")

Sie können auch Ihre eigene undefinierte Variable erstellen :

Object.defineProperty(this, 'u', {value : undefined});
console.log(u); //undefined

quelle
5

Um Ihre erste Frage zu beantworten, zwingt der Operator not ( !) alles, was ihm gegeben wird, in einen booleschen Wert. Also null, 0, false, NaNund ""(leere Zeichenkette) werden alle falsch erscheinen.

Skilldrick
quelle
Und auch leere Zeichenfolge und NaN (keine Zahl)
MBO
undefinedwird nicht als angezeigt false, es wird ein Fehler "ist nicht definiert" ausgegeben.
Tatu Ulmanen
Tatu Ulmanen: nicht wahr. if (undefined) {/* Do stuff*/}gibt keinen Fehler aus, da er undefinedals Eigenschaft des globalen Objekts existiert. Was einen Fehler gibt, ist so etwas wieif (someUndeclaredVariable) {/* Do stuff*/}
Tim Down
2

JavaScript, wie man eine Variable in der Kommandozeile auf undefiniert setzt:

Setzen Sie eine Variable im jsJavaScript-Befehlszeilenterminal, das mit Java unter Ubuntu 12.10 geliefert wird, auf undefiniert .

el@defiant ~ $ js

js> typeof boo
"undefined"

js> boo
typein:2: ReferenceError: boo is not defined

js> boo=5
5

js> typeof boo
"number"

js> delete(boo)
true

js> typeof boo
"undefined"

js> boo
typein:7: ReferenceError: boo is not defined

Wenn Sie eine Variable in einem Javascript auf undefiniert setzen:

Fügen Sie dies in myjs.html ein:

<html>
<body>
    <script type="text/JavaScript">
        document.write("aliens: " + aliens);
        document.write("typeof aliens: " + (typeof aliens));
        var aliens = "scramble the nimitz";
        document.write("found some aliens: " + (typeof aliens));
        document.write("not sayings its aliens but... " + aliens);
        aliens = undefined;
        document.write("aliens deleted");
        document.write("typeof aliens: " + (typeof aliens));
        document.write("you sure they are gone? " + aliens);
    </script>
</body>
</html>

Es druckt dies:

aliens: undefined
typeof aliens: undefined
found some aliens: string
not sayings its aliens but... scramble the nimitz
aliens deleted
typeof aliens: undefined
you sure they are gone? undefined

WARNUNG! Wenn Sie Ihre Variable auf undefiniert setzen, setzen Sie Ihre Variable auf eine andere Variable. Wenn eine hinterhältige Person ausgeführt undefined = 'rm -rf /';wird, erhalten Sie diesen Wert, wenn Sie Ihre Variable auf undefiniert setzen.

Sie fragen sich vielleicht, wie ich die Aliens mit undefiniertem Wert zu Beginn ausgeben und sie noch ausführen lassen kann. Es liegt am Heben von Javascript: http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

Eric Leschinski
quelle
2

Versuche dies:

// found on UglifyJS
variable = void 0;
Cqq Cqq
quelle
0

Das for if (something)und if (!something)wird häufig verwendet, um zu überprüfen, ob etwas definiert ist oder nicht. Zum Beispiel:

if (document.getElementById)

Der Bezeichner wird in einen booleschen Wert konvertiert und als undefinedinterpretiert false. Es gibt natürlich auch andere Werte (wie 0 und ''), die ebenfalls als interpretiert werdenfalse , aber entweder sollte der Bezeichner keinen solchen Wert haben, oder Sie sind zufrieden damit, einen solchen Wert als undefiniert zu behandeln.

Javascript verfügt über einen deleteOperator, mit dem ein Mitglied eines Objekts gelöscht werden kann. Abhängig vom Umfang einer Variablen (dh ob sie global ist oder nicht) können Sie sie löschen, um sie undefiniert zu machen.

Es gibt kein undefinedSchlüsselwort, das Sie als undefiniertes Literal verwenden können. Sie können Parameter in einem Funktionsaufruf weglassen, um sie undefiniert zu machen. Dies kann jedoch nur verwendet werden, indem weniger Parameter an die Funktion gesendet werden. Sie können keinen Parameter in der Mitte weglassen.

Guffa
quelle
0

Nur zum Spaß, hier ist eine ziemlich sichere Möglichkeit, einer Variablen "nicht zugewiesen" zuzuweisen. Damit dies zu einer Kollision kommt, muss jemand dem Prototyp für Object mit genau demselben Namen wie die zufällig generierte Zeichenfolge hinzugefügt haben. Ich bin sicher, dass der Zufallszeichenfolgengenerator verbessert werden könnte, aber ich habe nur eine Frage beantwortet: Generieren Sie zufällige Zeichenfolgen / Zeichen in JavaScript

Dies funktioniert, indem ein neues Objekt erstellt und versucht wird, auf eine Eigenschaft mit einem zufällig generierten Namen zuzugreifen, von dem wir annehmen, dass er nicht existiert und daher den Wert undefiniert hat.

function GenerateRandomString() {
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for (var i = 0; i < 50; i++)
        text += possible.charAt(Math.floor(Math.random() * possible.length));

    return text;
}

var myVar = {}[GenerateRandomString()];
rdans
quelle