Jak wyłączyć zmienną JavaScript?
Mam zmienną globalną w JavaScript (właściwie Właściwość window
, ale nie sądzę, że ma to znaczenie), która była już wypełniona przez poprzedni skrypt, ale nie chcę innego skryptu, który uruchomi się później, aby zobaczyć jego wartość lub że został nawet zdefiniowany.
Umieściłem some_var = undefined
i działa to w celu przetestowania typeof some_var == "undefined"
, ale naprawdę nie sądzę, aby to był właściwy sposób, aby to zrobić.
10 answers
Operator delete
usuwa właściwość z obiektu. Nie można usunąć zmiennej. Tak więc odpowiedź na pytanie zależy od tego, w jaki sposób globalna zmienna lub właściwość jest zdefiniowana.
(1) jeśli jest utworzony za pomocą var
, nie można go usunąć.
Na przykład:
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) jeśli zostanie utworzony bez var
, może zostać usunięty.
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
Wyjaśnienie Techniczne
1. Using var
W tym przypadku Referencja g_a
jest tworzona w ECMAScript Spec calls "Variable Environment" to jest dołączone do bieżącego zakresu-może to być kontekst wykonania funkcji w przypadku użycia var
wewnątrz funkcji (choć może to być nieco bardziej skomplikowane, jeśli weźmiemy pod uwagę let
) lub w przypadku kodu "globalnego" zmiennyEnvironment jest dołączony do obiektu globalnego (często window
).
Odwołania W Zmiennej nie są normalnie usuwalne-proces szczegółowo opisany w ECMAScript 10.5 wyjaśnia to szczegółowo, ale wystarczy powiedzieć, że jeśli kod nie jest wykonywany w kontekście eval
(którego używa większość konsol programistycznych opartych na przeglądarce), zmienne zadeklarowane przez var
nie mogą zostać usunięte.
2. Bez Użycia var
Podczas próby przypisania wartości do nazwy bez użycia słowa kluczowego var
, Javascript próbuje zlokalizować nazwane odniesienie w tym, co wywołuje Specyfikacja ECMAScript"LexicalEnvironment ", i główna różnica polega na tym, że LexicalEvironmentS są zagnieżdżone - to jest LexicalEnvironment ma rodzica (co spec ECMAScript nazywa "zewnętrznym odniesieniem do środowiska"), a gdy Javscript nie zlokalizuje odniesienia w LexicalEenvironment , wygląda w rodzicu LexicalEnvironment (jak opisano w 10.3.1 oraz 10.2.2.1). Najwyższy poziom leksykalne środowisko to "środowisko globalne", oraz jest to związane z obiektem globalnym, ponieważ jego odwołania są właściwościami obiektu globalnego. Jeśli więc spróbujesz uzyskać dostęp do nazwy, która nie została zadeklarowana za pomocą słowa kluczowego var
w bieżącym zakresie lub jakimkolwiek zewnętrznym zakresie, Javascript ostatecznie pobierze właściwość obiektu window
, aby służyć jako odniesienie. Jak dowiedzieliśmy się wcześniej, właściwości na obiektach mogą zostać usunięte.
Uwagi
-
Należy pamiętać, że
var
deklaracje są "podnoszone" - tzn. są zawsze uważa się, że miało to miejsce na początku zakresu, w którym się znajdują - choć nie inicjalizacja wartości, którą można wykonać w instrukcjivar
- która pozostaje tam, gdzie jest. Tak więc w poniższym kodziea
jest odniesieniem do zmiennej , a niewindow
Własności i jej wartość będzie10
na końcu kodu:function test() { a = 5; var a = 10; }
Powyższa dyskusja dotyczy sytuacji, gdy" tryb ścisły " nie jest włączony. Reguły wyszukiwania są nieco inne, gdy Używanie "trybu ścisłego" i odniesień leksykalnych, które rozwiązałyby się we właściwościach okna bez "trybu ścisłego", spowoduje błędy" niezgłoszonej zmiennej "w"trybie ścisłym". Nie bardzo rozumiem, gdzie to jest określone, ale jego jak przeglądarki zachowują się.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-20 12:32:09
@scunlife ' s answer will work, but formalnie it should be
delete window.some_var;
Delete ma być no-op, gdy obiekt docelowy nie jest właściwością obiektu. np.,
(function() {
var foo = 123;
delete foo; // wont do anything, foo is still 123
var bar = { foo: 123 };
delete bar.foo; // foo is gone
}());
Ale ponieważ zmienne globalne są rzeczywiście członkami obiektu window, to działa.
Gdy używane są łańcuchy prototypów, użycie delete staje się bardziej złożone, ponieważ usuwa tylko właściwość z obiektu docelowego, a nie prototypu. np.,
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.
Więc bądź ostrożny.
EDIT: moja odpowiedź brzmi nieco niedokładne (patrz "nieporozumienia" na końcu). Link wyjaśnia wszystkie krwawe szczegóły, ale podsumowanie jest takie, że mogą występować duże różnice między przeglądarkami i w zależności od obiektu, z którego usuwasz. delete object.someProp
powinny być ogólnie bezpieczne tak długo, jak object !== window
. Nadal nie używałbym go do usuwania zmiennych zadeklarowanych przez var
, chociaż można to zrobić w odpowiednich okolicznościach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-01-11 17:11:04
Jeśli domyślnie deklarujesz zmienną bez var
, właściwym sposobem byłoby użycie delete foo
.
Jednak po usunięciu go, jeśli spróbujesz użyć go w operacji takiej jak dodanie, ReferenceError
zostanie wyrzucony, ponieważ nie możesz dodać ciągu znaków do niezgłoszonego, niezdefiniowanego identyfikatora. Przykład:
x = 5;
delete x
alert('foo' + x )
// ReferenceError: x is not defined
W niektórych sytuacjach bezpieczniejsze może być przypisanie go do false, null lub undefined, aby został zadeklarowany i nie wyrzuci tego typu błędu.
foo = false
Zauważ, że w ECMAScript null
, false
, undefined
, 0
, NaN
, lub ''
wszystkie ocenią na false
. Po prostu upewnij się, że nie używasz operatora !==
, ale zamiast tego !=
podczas sprawdzania typu dla wartości logicznych i nie chcesz sprawdzania tożsamości (więc null
będzie == false
i false == undefined
).
Zauważ również, że delete
nie "usuwa" referencji, a jedynie właściwości bezpośrednio na obiekcie, np.:
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)
Jeśli zadeklarowałeś zmienną za pomocą var
nie możesz jej usunąć:
(function() {
var x = 5;
alert(delete x)
// false
})();
W Rhino:
js> var x
js> delete x
false
Nie można też usunąć niektórych predefiniowanych właściwości, takich jak Math.PI
:
js> delete Math.PI
false
Istnieją pewne dziwne wyjątki od delete
jak w każdym języku, jeśli zależy ci na tyle powinieneś przeczytać:
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-08-13 14:19:30
some_var = null;
//or remove it..
delete some_var;
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-10-20 19:24:58
TLDR: proste zdefiniowane zmienne (Bez var
, let
, const
) można usunąć za pomocą delete
. W przypadku stosowania var
, let
, const
- nie można ich usunąć ani za pomocą delete
, ani za pomocą Reflect.deleteProperty
.
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 pokazuje to samo zachowanie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-05 15:13:36
ECMAScript 2015 oferuje API Reflect. Możliwe jest usunięcie właściwości obiektu za pomocą Reflect.deleteProperty():
Reflect.deleteProperty(myObject, 'myProp');
// it is equivalent to:
delete myObject.myProp;
delete myObject['myProp'];
Aby usunąć właściwość obiektu global window
:
Reflect.deleteProperty(window, 'some_var');
W niektórych przypadkach właściwości nie można usunąć (gdy właściwość nie jest konfigurowalna) i wtedy ta funkcja zwraca false
(jak również operator delete ). W innych przypadkach zwraca true
:
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
Istnieje różnica między funkcją deleteProperty
a operatorem delete
podczas uruchamiania w tryb ścisły:
'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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-25 16:17:32
Operator delete usuwa właściwość z obiektu.
delete object.property
delete object['property']
Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
Zgodnie z pytaniem potrzebujesz jednego z następujących pytań
delete some_var;
delete window.some_var;
delete window['some_var'];
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-12-14 21:11:58
Oprócz tego, co wszyscy napisali, zauważ również, że delete
Zwraca wartość logiczną. Może Ci powiedzieć, czy usunięcie się powiodło, czy nie.
UPDATE:
Testując najnowszą Chrome, wszystko można było usunąć. delete
funkcja zwróciła true
dla wszystkich następujących metod i faktycznie je usunęła:
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
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-14 15:09:24
Zmienne, w przeciwieństwie do prostych właściwości, mają atrybut [[konfigurowalny]] , co oznacza niemożność usunięcia zmiennej za pomocą operatora delete . Istnieje jednak jeden kontekst wykonania, na który zasada ta nie ma wpływu. Jest to kontekst eval : tam [[konfigurowalny]] atrybut nie jest ustawiony dla zmiennych.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-01-25 04:46:55
Nie możesz usunąć zmiennej, jeśli zadeklarowałeś ją (za pomocą var x;) przy pierwszym użyciu. Jeśli jednak twoja zmienna x pojawiła się w skrypcie po raz pierwszy bez deklaracji, możesz użyć operatora delete (delete x;) i twoja zmienna zostanie usunięta, bardzo podobnie jak usunięcie elementu tablicy lub usunięcie właściwości obiektu.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-03-31 17:48:42