Как отключить переменную 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 называет"VariableEnvironment", который прикреплен к текущей области-это может быть контекст выполнения функции a в случае использования var внутри функции (хотя это может быть немного сложнее, если учесть let) или в случае "глобального" кодекса VariableEnvironment присоединяется к глобальному объекту (часто window).

ссылки в the VariableEnvironment обычно не удаляются-процесс подробно описан в ECMAScript 10.5 объясняет это подробно, но достаточно сказать, что если ваш код выполняется в элементе eval контекст (который использует большинство консолей разработки на основе браузера), а затем переменные, объявленные с var невозможно удалить.

2. Без Использования var

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


@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
})();

In Rhino:

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.

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 показывает такое же поведение.


предложения ECMAScript 2015 отражают API. Свойство объекта можно удалить с помощью отразить.deleteProperty():

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

удалить свойство global


оператор 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 возвращает логическое значение. Он может сказать вам, было ли удаление успешным или нет.

обновление:

тестирование на последнем Chrome, все было deleltable.


переменные, в отличие от простых свойств, имеют атрибут [[настраивать]], что означает невозможность удалить переменную через удалить оператора. Однако существует один контекст выполнения, на который это правило не влияет. Это eval контекст: там [[настраиваемый]] атрибут не установлен для переменных.


вы не можете удалить переменную, если вы объявили ее (с var x;) во время первого использования. Однако, если ваша переменная x впервые появилась в скрипте без объявления, вы можете использовать оператор delete (delete x;) и ваша переменная будет удалена, очень похоже на удаление элемента массива или удаление свойства объекта.