web-dev-qa-db-de.com

Wie lösche ich eine JavaScript-Variable?

Ich habe eine globale Variable in JavaScript (eigentlich eine window -Eigenschaft, aber ich glaube nicht, dass es wichtig ist), die bereits von einem vorherigen Skript ausgefüllt wurde, aber ich möchte nicht, dass ein anderes Skript, das später ausgeführt wird, dessen Wert anzeigt oder dass es sogar definiert wurde.

Ich habe some_var = undefined eingegeben und es funktioniert zum Testen von typeof some_var == "undefined", aber ich glaube wirklich nicht, dass es der richtige Weg ist, dies zu tun.

Was denkst du?

561
Guss

Der Operator delete entfernt eine Eigenschaft aus einem Objekt. Eine Variable kann nicht entfernt werden. Die Antwort auf die Frage hängt also davon ab, wie die globale Variable oder Eigenschaft definiert ist.

(1) Wenn es mit var erstellt wurde, kann es nicht gelöscht werden.

Zum Beispiel:

var g_a = 1; //create with var, g_a is a variable 
delete g_a; //return false
console.log(g_a); //g_a is still 1

(2) Wenn es ohne var erstellt wurde, kann es gelöscht werden.

g_b = 1; //create without var, g_b is a property 
delete g_b; //return true
console.log(g_b); //error, g_b is not defined

Technische Erklärung

1. Verwenden von var

In diesem Fall wird die Referenz g_a in dem erstellt, was die ECMAScript-Spezifikation aufruft. " VariableEnvironment msgstr "" "ist an den aktuellen Gültigkeitsbereich angehängt - dies kann der Kontext der Funktionsausführung sein, wenn var in einer Funktion verwendet wird (obwohl dies unter Berücksichtigung von let etwas komplizierter sein kann) oder wenn" globaler "Code verwendet wird Die VariableEnvironment wird an das globale Objekt angehängt (häufig window).

Referenzen in der VariableEnvironment sind normalerweise nicht löschbar - der in ECMAScript 10.5 beschriebene Prozess erläutert dies ausführlich. Es genügt jedoch zu sagen, dass mit eval deklarierte Variablen nur gelöscht werden können, wenn Ihr Code in einem var-Kontext ausgeführt wird (den die meisten browserbasierten Entwicklungskonsolen verwenden).

2. Ohne Verwendung von var

Wenn Sie versuchen, einem Namen einen Wert zuzuweisen, ohne das Schlüsselwort var zu verwenden, versucht Javascript, den benannten Verweis in dem zu finden, was die ECMAScript-Spezifikation aufruft " LexicalEnvironment ", und der Hauptunterschied ist, dass LexicalEvironment s verschachtelt sind - das ist ein LexicalEnvironment hat ein übergeordnetes Element (was die ECMAScript-Spezifikation als "äußere Umgebungsreferenz" bezeichnet) und wenn Javscript die Referenz in einer LexicalEenvironment , sieht es in der übergeordneten LexicalEnvironment aus (wie in 10.3.1 und 10.2.2.1 ). Die oberste Ebene LexicalEnvironment ist die " globale Umgebung ", und das ist an das globale Objekt gebunden, indem seine Referenzen die Eigenschaften des globalen Objekts sind. Wenn Sie also versuchen, auf einen Namen zuzugreifen, der nicht mit einem Schlüsselwort var im aktuellen Bereich oder einem anderen äußeren Bereich deklariert wurde, ruft Javascript möglicherweise eine Eigenschaft des Objekts window ab, die als Referenz dient. Wie wir bereits erfahren haben, können Eigenschaften von Objekten gelöscht werden.

Anmerkungen

  1. Es ist wichtig zu bedenken, dass var-Deklarationen "hochgezogen" sind - dh, sie werden immer als am Anfang des Gültigkeitsbereichs aufgetreten betrachtet, in dem sie sich befinden - obwohl nicht die Wertinitialisierung, die in einer var-Anweisung vorgenommen werden kann - die dort verbleibt es ist. Im folgenden Code ist a eine Referenz aus der VariableEnvironment und nicht die Eigenschaft window, und ihr Wert wird am Ende von 10 sein der Code:

    function test() { a = 5; var a = 10; }

  2. Die obige Diskussion ist, wenn "strikter Modus" nicht aktiviert ist. Lookup-Regeln sind etwas anders, wenn Sie den "strengen Modus" verwenden, und lexikalische Verweise, die in Fenstereigenschaften ohne "strengen Modus" aufgelöst worden wären, lösen im "strengen Modus" "nicht deklarierte Variablenfehler" aus. Ich habe nicht wirklich verstanden, wo dies angegeben ist, aber wie sich Browser verhalten.

404
Dayong

Die Antwort von @scunlife wird funktionieren, aber technisch sollte es so sein

delete window.some_var; 

delete soll ein No-Op sein, wenn das Ziel keine Objekteigenschaft ist. z.B.,

(function() {
   var foo = 123;
   delete foo; // wont do anything, foo is still 123
   var bar = { foo: 123 };
   delete bar.foo; // foo is gone
}());

Aber da globale Variablen tatsächlich Mitglieder des Fensterobjekts sind, funktioniert es.

Wenn Prototypketten beteiligt sind, wird die Verwendung von delete komplexer, da nur die Eigenschaft vom Zielobjekt und nicht der Prototyp entfernt wird. z.B.,

function Foo() {}
Foo.prototype = { bar: 123 };
var foo = new Foo();
// foo.bar is 123
foo.bar = 456;
// foo.bar is now 456
delete foo.bar;
// foo.bar is 123 again.

Also sei vorsichtig.

EDIT: Meine Antwort ist etwas ungena (siehe "Missverständnisse" am Ende). Der Link erklärt alle wichtigen Details, aber die Zusammenfassung ist, dass es große Unterschiede zwischen den Browsern geben kann und dies von dem Objekt abhängt, aus dem Sie löschen. delete object.someProp sollte im Allgemeinen sicher sein, solange object !== window. Ich würde es immer noch nicht zum Löschen von Variablen verwenden, die mit var deklariert wurden, obwohl Sie dies unter den richtigen Umständen können.

274
noah

Wenn Sie die Variable implizit ohne var deklarieren, ist der richtige Weg, delete foo zu verwenden.

Wenn Sie jedoch versuchen, dies in einem Vorgang wie dem Hinzufügen zu verwenden, wird ein ReferenceError ausgegeben, da Sie einer nicht deklarierten, nicht definierten Kennung keine Zeichenfolge hinzufügen können. Beispiel:

x = 5;
delete x
alert('foo' + x )
// ReferenceError: x is not defined

In einigen Situationen kann es sicherer sein, sie false, null oder undefined zuzuweisen, damit sie deklariert wird und diese Art von Fehler nicht auslöst.

foo = false

Beachten Sie, dass in ECMAScript null, false, undefined, 0, NaN oder '' alle zu false ausgewertet würden. Stellen Sie nur sicher, dass Sie nicht den !== -Operator, sondern != verwenden, wenn Sie nach Booleschen Werten suchen und keine Identitätsprüfung wünschen (also würden null== false und false == undefined).

Beachten Sie auch, dass delete keine Referenzen "löscht", sondern nur Eigenschaften direkt am Objekt, z.

bah = {}, foo = {}; bah.ref = foo;

delete bah.ref;
alert( [bah.ref, foo ] )
// ,[object Object] (it deleted the property but not the reference to the other object)

Wenn Sie eine Variable mit var deklariert haben, können Sie sie nicht löschen:

(function() {
    var x = 5;
    alert(delete x)
    // false
})();

In Rhino:

js> var x
js> delete x
false

Sie können auch einige vordefinierte Eigenschaften wie Math.PI nicht löschen:

js> delete Math.PI
false

Wie bei jeder Sprache gibt es auch bei delete einige Ausnahmen. Wenn Sie sich genug darum kümmern, sollten Sie Folgendes lesen:

34
meder omuraliev
some_var = null;

//or remove it..
delete some_var;
29
scunliffe

TLDR: Einfache definierte Variablen (ohne var, let, const) können mit delete gelöscht werden. Wenn Sie var, let, const verwenden, konnten sie weder mit delete noch mit Reflect.deleteProperty gelöscht werden.

Chrome 55:

simpleVar = "1";
"1"
delete simpleVar;
true
simpleVar;
VM439:1 Uncaught ReferenceError: simpleVar is not defined
    at <anonymous>:1:1
(anonymous) @ VM439:1
var varVar = "1";
undefined
delete varVar;
false
varVar;
"1"
let letVar = "1";
undefined
delete letVar;
true
letVar;
"1"
const constVar="1";
undefined
delete constVar;
true
constVar;
"1"
Reflect.deleteProperty (window, "constVar");
true
constVar;
"1"
Reflect.deleteProperty (window, "varVar");
false
varVar;
"1"
Reflect.deleteProperty (window, "letVar");
true
letVar;
"1"

FF Nightly 53.0a1 zeigt dasselbe Verhalten.

14
Serj.by

ECMAScript 2015 bietet Reflect API. Es ist möglich, Objekteigenschaften mit Reflect.deleteProperty () zu löschen:

Reflect.deleteProperty(myObject, 'myProp');
// it is equivalent to:
delete myObject.myProp;
delete myObject['myProp'];

So löschen Sie die Eigenschaft des globalen Objekts window:

Reflect.deleteProperty(window, 'some_var');

In einigen Fällen können Eigenschaften nicht gelöscht werden (wenn die Eigenschaft nicht konfigurierbar ist) und diese Funktion gibt dann false (sowie Löschoperator ) zurück. In anderen Fällen wird true zurückgegeben:

Object.defineProperty(window, 'some_var', {
    configurable: false,
    writable: true,
    enumerable: true,
    value: 'some_val'
});

var frozen = Object.freeze({ myProperty: 'myValue' });
var regular = { myProperty: 'myValue' };
var blank = {};

console.log(Reflect.deleteProperty(window, 'some_var')); // false
console.log(window.some_var); // some_var

console.log(Reflect.deleteProperty(frozen, 'myProperty')); // false
console.log(frozen.myProperty); // myValue

console.log(Reflect.deleteProperty(regular, 'myProperty')); // true
console.log(regular.myProperty); // undefined

console.log(Reflect.deleteProperty(blank, 'notExistingProperty')); // true
console.log(blank.notExistingProperty); // undefined

Es gibt einen Unterschied zwischen der Funktion deleteProperty und dem Operator delete, wenn sie im strikten Modus ausgeführt werden:

'use strict'

var frozen = Object.freeze({ myProperty: 'myValue' });

Reflect.deleteProperty(frozen, 'myProperty'); // false
delete frozen.myProperty;
// TypeError: property "myProperty" is non-configurable and can't be deleted
3
madox2

Der Operator delete entfernt eine Eigenschaft aus einem Objekt.

delete object.property
delete object['property']

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete

Je nach Fragestellung benötigen Sie eine der folgenden Angaben

delete some_var;
delete window.some_var;
delete window['some_var'];
2
Swarnendu Paul

Variablen haben im Gegensatz zu einfachen Eigenschaften das Attribut [[Konfigurierbar]], was bedeutet, dass es nicht möglich ist, eine Variable über den Befehl delete zu entfernen. Operator. Es gibt jedoch einen Ausführungskontext, auf den sich diese Regel nicht auswirkt. Dies ist der eval Kontext: Das Attribut [[Konfigurierbar]] ist für Variablen nicht festgelegt.

2

Beachten Sie zusätzlich zu dem, was alle geschrieben haben, auch, dass delete einen Booleschen Wert zurückgibt. Es kann Ihnen sagen, ob das Löschen erfolgreich war oder nicht.

PDATE:

Beim Testen auf dem neuesten Chrome war alles deleltable. Die Funktion delete hat true für alle folgenden Methoden zurückgegeben und diese tatsächlich entfernt:

implicit_global = 1;
window.explicit_global = 1;
function_set = function() {};
function function_dec() { };
var declared_variable = 1;

delete delete implicit_global; // true, tested on Chrome 52
delete window.explicit_global; // true, tested on Chrome 52
delete function_set; // true, tested on Chrome 52
delete function_dec; // true, tested on Chrome 52
delete declared_variable; // true, tested on Chrome 52
2
oriadam

Sie können eine Variable nicht löschen, wenn Sie sie zum Zeitpunkt der ersten Verwendung (mit var x;) deklariert haben. Wenn Ihre Variable x jedoch zum ersten Mal ohne Deklaration im Skript angezeigt wird, können Sie den Operator delete (delete x;) verwenden, und Ihre Variable wird gelöscht, ähnlich wie beim Löschen eines Elements eines Arrays oder einer Eigenschaft eines Objekts .

1

Ich bin etwas verwirrt. Wenn Sie lediglich möchten, dass ein Variablenwert nicht an ein anderes Skript übergeben wird, müssen Sie die Variable nicht aus dem Gültigkeitsbereich löschen. Machen Sie die Variable einfach ungültig und prüfen Sie dann explizit, ob sie null ist oder nicht. Warum müssen Sie sich die Mühe machen, die Variable aus dem Gültigkeitsbereich zu löschen? Welchen Zweck hat dieser Server, der nicht aufheben kann?

foo = null;
if(foo === null) or if(foo !== null)
0
designdrumm