Как отключить переменную JavaScript?
У меня есть глобальная переменная в JavaScript (на самом деле свойство window, но я не думаю, что это имеет значение), которая уже была заполнена предыдущим скриптом, но я не хочу, чтобы другой скрипт, который будет работать позже, увидел ее значение или что она была даже определена.
Я поставил some_var = undefined, и это работает с целью тестирования typeof some_var == "undefined", но я действительно не думаю, что это правильный путь.
Что вы думаете?
10 ответов:
Оператор
deleteудаляет свойство из объекта. Он не может удалить переменную. Таким образом, ответ на этот вопрос зависит от того, как определяется глобальная переменная или свойство.(1) если он создан с помощью
var, он не может быть удален.Например:
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) если он создан без
var, его можно удалить.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Техническое Объяснение
1. Использование
varВ этом случае Ссылка
g_aсоздается в том, что Вызовы спецификации ECMAScript "переменная среда" это может быть контекст выполнения функции a в случае использованияvarвнутри функции (хотя это может быть немного сложнее, если вы рассматриваетеlet) или в случае "глобального" кода переменная среда прикреплена к глобальному объекту (частоwindow).Ссылки в переменном окружении обычно не удаляются-процесс подробно описано в ECMAScript 10.5, но достаточно сказать, что если ваш код не выполняется в контексте
eval(который используется большинством консолей разработки на основе браузера), то переменные, объявленные с помощьюvar, не могут быть удалены.2. Без Использования
varПри попытке присвоить значение имени без использования ключевого слова
varJavascript пытается найти именованную ссылку в том, что вызывает спецификация ECMAScript"лексическая среда ", и главное отличие заключается в том, что LexicalEvironmentы вложены - то есть LexicalEnvironment и родителей (что в ECMAScript спецификаций вызовы "внешней среды ссылка") и при контрактной работе с разными компаниями не удается найти ссылку в LexicalEenvironment, он смотрит в Родительском LexicalEnvironment (подробнее 10.3.1 и 10.2.2.1). Верхний уровень лексической среды - это "глобальная окружающая среда", и еще это связано с глобальным объектом в том смысле, что его ссылки являются свойствами глобального объекта. Таким образом, если вы попытаетесь получить доступ к имени, которое не было объявлено с помощью ключевого словаvarв текущей области или любых внешних областях, Javascript в конечном итоге получит свойство объектаwindow, чтобы служить в качестве этой ссылки. Как мы уже выяснили, свойства объектов могут быть удалены.Примечания
Важно помнить, что
varобъявления "подняты" - т. е. всегда считается, что это произошло в начале области, в которой они находятся - хотя и не инициализация значения, которая может быть выполнена в оператореvar, - которая остается там, где она есть. Таким образом, в следующем кодеaявляется ссылкой из переменной среды , а не свойствомwindow, и его значение будет10в конце кода:
function test() { a = 5; var a = 10; }Выше обсуждается, когда "строгий режим" не включен. Правила поиска немного отличаются, когда использование " строгого режима "и лексических ссылок, которые разрешили бы свойства окна без" строгого режима", вызовет ошибки" необъявленной переменной "в"строгом режиме". Я действительно не понял, где это указано, но его, как браузеры ведут себя.
Ответ @ scunlife будет работать, но технически это должно быть
delete window.some_var;Delete должен быть no-op, когда цель не является свойством объекта. например,
Но поскольку глобальные переменные на самом деле являются членами объекта window, это работает.(function() { var foo = 123; delete foo; // wont do anything, foo is still 123 var bar = { foo: 123 }; delete bar.foo; // foo is gone }());Когда задействованы цепочки прототипов, использование delete становится более сложным, потому что оно удаляет только свойство из целевого объекта, а не прототип. например,
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., поэтому будьте осторожны.
EDIT: мой ответ таков несколько неточно (см. "заблуждения" в конце). Ссылка объясняет все кровавые детали, но суть в том, что могут быть большие различия между браузерами и в зависимости от объекта, из которого вы удаляете.
delete object.somePropобычно должно быть безопасно до тех пор, покаobject !== window. Я по-прежнему не буду использовать его для удаления переменных, объявленных с помощьюvar, хотя вы можете при определенных обстоятельствах.
Если вы неявно объявляете переменную без
var, правильным способом было бы использоватьdelete foo.Однако после его удаления, Если вы попытаетесь использовать его в такой операции, как добавление, будет брошен
ReferenceError, потому что вы не можете добавить строку к необъявленному, неопределенному идентификатору. Пример:x = 5; delete x alert('foo' + x ) // ReferenceError: x is not definedВ некоторых ситуациях может быть безопаснее присвоить ему значение false, null или undefined, чтобы он был объявлен и не создавал ошибок такого типа.
foo = falseОбратите внимание, что в ECMAScript
null,false,undefined,0,NaN, или''все оценивалось бы вfalse. Просто убедитесь, что вы не используете оператор!==, а вместо него!=при проверке типа на логические значения, и вы не хотите проверять идентичность (поэтомуnullбудет== falseиfalse == undefined).Также обратите внимание, что
deleteне "удаляет" ссылки, а просто свойства непосредственно на объекте, например: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)Если вы объявили переменную с
var, Вы не можете удалить ее:(function() { var x = 5; alert(delete x) // false })();В Носорог:
js> var x js> delete x falseТакже нельзя удалить некоторые предопределенные свойства, такие как
Math.PI:js> delete Math.PI falseЕсть некоторые странные исключения из
delete, как и в любом языке, если вы достаточно заботитесь, вы должны прочитать:
TLDR: простые определенные переменные (без
var,let,const) может быть удален с помощьюdelete. Если вы используетеvar,let,const- их нельзя было удалить ни сdelete, ни сReflect.deleteProperty.Хром 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 показывает то же самое поведение.
ECMAScript 2015 предлагает Reflect API. Свойство объекта можно удалить с помощью Reflect.deleteProperty():
Reflect.deleteProperty(myObject, 'myProp'); // it is equivalent to: delete myObject.myProp; delete myObject['myProp'];Удалить свойство глобального объекта
window:Reflect.deleteProperty(window, 'some_var');В некоторых случаях свойства не могут быть удалены (если свойство не настраивается), и тогда эта функция возвращает
false(а также оператор удаления). В других случаях возвращает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Существует разница между функцией
deletePropertyи операторомdeleteпри запуске в строгий режим:'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
Оператор delete удаляет свойство из объекта.
delete object.property delete object['property']Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
В соответствии с вопросом вам нужно одно из следующих
delete some_var; delete window.some_var; delete window['some_var'];
В дополнение к тому, что все написали, также обратите внимание, что
deleteвозвращает boolean. Он может сказать вам, было ли удаление успешным или нет.Обновление:
Тестирование на последнем Chrome, все было deleltable.
deleteфункция возвращаетtrueдля всех следующих методов и фактически удаляет их: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]], означающий невозможность удалить переменную с помощью оператора delete. Однако есть один контекст выполнения, на который это правило не влияет. Это контекст eval : там [[конфигурируемый]] атрибут не установлен для переменных.
Вы не можете удалить переменную, если вы объявили ее (с var x;) во время первого использования. Однако если ваша переменная x впервые появилась в скрипте без объявления, то вы можете использовать оператор delete (delete x;) и ваша переменная будет удалена, очень похоже на удаление элемента массива или удаление свойства объекта.
Comments