Как отключить переменную JavaScript?



У меня есть глобальная переменная в JavaScript (на самом деле свойство window, но я не думаю, что это имеет значение), которая уже была заполнена предыдущим скриптом, но я не хочу, чтобы другой скрипт, который будет работать позже, увидел ее значение или что она была даже определена.



Я поставил some_var = undefined, и это работает с целью тестирования typeof some_var == "undefined", но я действительно не думаю, что это правильный путь.



Что вы думаете?

565   10  

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

При попытке присвоить значение имени без использования ключевого слова var Javascript пытается найти именованную ссылку в том, что вызывает спецификация ECMAScript"лексическая среда ", и главное отличие заключается в том, что LexicalEvironmentы вложены - то есть LexicalEnvironment и родителей (что в ECMAScript спецификаций вызовы "внешней среды ссылка") и при контрактной работе с разными компаниями не удается найти ссылку в LexicalEenvironment, он смотрит в Родительском LexicalEnvironment (подробнее 10.3.1 и 10.2.2.1). Верхний уровень лексической среды - это "глобальная окружающая среда", и еще это связано с глобальным объектом в том смысле, что его ссылки являются свойствами глобального объекта. Таким образом, если вы попытаетесь получить доступ к имени, которое не было объявлено с помощью ключевого слова var в текущей области или любых внешних областях, Javascript в конечном итоге получит свойство объекта window, чтобы служить в качестве этой ссылки. Как мы уже выяснили, свойства объектов могут быть удалены.

Примечания

  1. Важно помнить, что var объявления "подняты" - т. е. всегда считается, что это произошло в начале области, в которой они находятся - хотя и не инициализация значения, которая может быть выполнена в операторе var, - которая остается там, где она есть. Таким образом, в следующем коде a является ссылкой из переменной среды , а не свойством window, и его значение будет 10 в конце кода:

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

  2. Выше обсуждается, когда "строгий режим" не включен. Правила поиска немного отличаются, когда использование " строгого режима "и лексических ссылок, которые разрешили бы свойства окна без" строгого режима", вызовет ошибки" необъявленной переменной "в"строгом режиме". Я действительно не понял, где это указано, но его, как браузеры ведут себя.

Ответ @ scunlife будет работать, но технически это должно быть

delete window.some_var; 

Delete должен быть no-op, когда цель не является свойством объекта. например,

(function() {
   var foo = 123;
   delete foo; // wont do anything, foo is still 123
   var bar = { foo: 123 };
   delete bar.foo; // foo is gone
}());
Но поскольку глобальные переменные на самом деле являются членами объекта window, это работает.

Когда задействованы цепочки прототипов, использование 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, как и в любом языке, если вы достаточно заботитесь, вы должны прочитать:

some_var = null;

//or remove it..
delete some_var;

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

    Ничего не найдено.