Question Comment désactiver une variable JavaScript?


J'ai une variable globale en JavaScript (en fait un window propriété, mais je ne pense pas que cela soit important) qui était déjà peuplé par un script précédent mais je ne veux pas d'un autre script qui fonctionnera plus tard pour voir sa valeur ou même qu'il soit défini.

J'ai mis some_var = undefined et cela fonctionne dans le but de tester typeof some_var == "undefined" mais je ne pense vraiment pas que ce soit la bonne façon de s'y prendre.

Qu'est-ce que tu penses?


492
2017-10-20 19:23


origine


Réponses:


Je sais que c'est un vieux sujet, mais la réponse sélectionnée n'est pas assez claire pour moi.

Le point est l'opérateur de suppression supprime une propriété d'un objet. Il ne peut pas supprimer une variable. La réponse à la question dépend donc de la définition de la variable ou de la propriété globale.

(1) S'il est créé avec var, il ne peut pas être supprimé.

Par exemple:

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) S'il est créé sans var, il peut être supprimé.

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

Explication technique

1. Utilisation var

Dans ce cas la référence g_a est créé dans ce que les appels d'ECMAScript spécifient "VariableEnvironment"qui est attaché à la portée actuelle - cela peut être le contexte d'exécution d'une fonction dans le cas de l'utilisation var à l'intérieur d'une fonction (même si cela peut devenir un peu plus compliqué quand on considère let) ou dans le cas du code "global" VariableEnvironment est attaché à l'objet global (souvent window).

Références dans le VariableEnvironment ne sont normalement pas effaçables - le processus détaillé ECMAScript 10.5 explique cela en détail, mais il suffit de dire que si votre code n'est pas exécuté dans un eval contexte (que la plupart des consoles de développement basées sur un navigateur utilisent), puis les variables déclarées avec var ne peut pas être supprimé.

2. Sans utiliser var

Lorsque vous essayez d'attribuer une valeur à un nom sans utiliser le var mot-clé, Javascript essaie de localiser la référence nommée dans ce que spécifient les appels ECMAScript "Environnement Lexique", et la principale différence est que LexicalEvironments sont imbriqués - c'est un Environnement Lexique a un parent (ce que la spécification ECMAScript appelle "référence d'environnement externe") et quand Javscript ne parvient pas à localiser la référence dans un Environnement lexical, il regarde dans le parent Environnement Lexique (comme détaillé dans 10.3.1 et 10.2.2.1). Le plus haut niveau Environnement Lexique est le "environnement global", et cela est lié à l'objet global dans la mesure où ses références sont les propriétés de l'objet global.Alors si vous essayez d'accéder à un nom qui n'a pas été déclaré en utilisant un var mot-clé dans la portée actuelle ou des étendues externes, Javascript finira par récupérer une propriété du window objet pour servir de cette référence. Comme nous l’avons appris auparavant, les propriétés des objets peuvent être supprimées.

Remarques

  1. Il est important de se rappeler que var les déclarations sont "hissées" - c'est-à-dire qu'elles sont toujours considérées comme arrivées au début de la portée dans laquelle elles se trouvent - mais pas l'initialisation de la valeur qui peut être faite dans un vardéclaration - qui est laissé où il est. Donc, dans le code suivant, a est une référence de la VariableEnvironment et pas le window propriété et sa valeur sera 10 à la fin du code:

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

  2. La discussion ci-dessus est lorsque le "mode strict" n'est pas activé. Les règles de recherche sont un peu différentes lors de l'utilisation du "mode strict" et les références lexicales qui se seraient résolues aux propriétés de la fenêtre sans "mode strict" produiront des erreurs "variables non déclarées" sous "mode strict". Je n'ai pas vraiment compris où cela est spécifié, mais c'est le comportement des navigateurs.


329
2017-09-18 18:33



réponse @ scunlife va fonctionner, mais techniquement, il devrait être

delete window.some_var; 

delete est supposé être un no-op lorsque la cible n'est pas une propriété d'objet. par exemple.,

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

Mais comme les variables globales sont en fait membres de l'objet window, cela fonctionne.

Lorsque des chaînes prototypes sont impliquées, l'utilisation de la suppression devient plus complexe car elle supprime uniquement la propriété de l'objet cible, et non le prototype. par exemple.,

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.

Donc sois prudent.

EDIT: Ma réponse est quelque peu inexact (Voir "Les idées fausses" à la fin). Le lien explique tous les détails sanglants, mais le résumé est qu'il peut y avoir de grandes différences entre les navigateurs et en fonction de l'objet que vous supprimez. delete object.someProp devrait généralement être sûr aussi longtemps que object !== window. Je ne voudrais toujours pas l'utiliser pour supprimer les variables déclarées avec var Bien que vous pouvez dans les bonnes circonstances.


265
2017-10-20 19:47



Si vous déclarez implicitement la variable sans var, la bonne façon serait d'utiliser delete foo.

Cependant, après l'avoir supprimé, si vous essayez d'utiliser ceci dans une opération telle que ReferenceError sera lancé parce que vous ne pouvez pas ajouter une chaîne à un identificateur non déclaré, non défini. Exemple:

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

Il peut être plus sûr dans certaines situations de l'assigner à false, null, ou indéfini afin qu'il soit déclaré et ne lancera pas ce type d'erreur.

foo = false

Notez que dans ECMAScript null, false, undefined, 0, NaN, ou '' tous évalueraient à false. Assurez-vous de ne pas utiliser le !== opérateur mais à la place != lors de la vérification de type pour les booléens et vous ne voulez pas de vérification d'identité (donc null aurait == false et false == undefined).

Notez également que delete ne supprime pas les références, mais seulement les propriétés directement sur l'objet, par exemple:

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)

Si vous avez déclaré une variable avec var vous ne pouvez pas le supprimer:

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

En Rhino:

js> var x
js> delete x
false

Vous ne pouvez pas non plus supprimer certaines propriétés prédéfinies Math.PI:

js> delete Math.PI
false

Il y a quelques exceptions étranges à delete comme avec n'importe quelle langue, si vous vous en souciez, vous devriez lire:


34
2017-10-20 19:31



some_var = null;

//or remove it..
delete some_var;

31
2017-10-20 19:24



TLDR: variables simples définies (sans var, let, const) pourrait être supprimé avec delete. Si tu utilises var, let, const - ils ne pouvaient être supprimés ni avec delete ni avec 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 montre le même comportement.


6
2018-01-05 15:13



ECMAScript 2015 propose une API Reflect. Il est possible de supprimer la propriété d'objet avec Reflect.deleteProperty ():

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

Pour supprimer la propriété de global window objet:

Reflect.deleteProperty(window, 'some_var');

Dans certains cas, les propriétés ne peuvent pas être supprimées (lorsque la propriété n'est pas configurable), puis cette fonction retourne false (aussi bien que supprimer l'opérateur). Dans d'autres cas, retourne 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

Il y a une différence entre deleteProperty fonction et delete opérateur lorsqu'il est exécuté en mode strict:

'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
2018-01-25 15:37



L'opérateur delete supprime une propriété d'un objet.

delete object.property
delete object['property']

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

Selon la question, vous avez besoin d'un des suivants

delete some_var;
delete window.some_var;
delete window['some_var'];

2
2017-12-14 21:11



En plus de ce que tout le monde avait écrit, notez aussi que delete renvoie un booléen. Il peut vous dire si la suppression a réussi ou non.

METTRE À JOUR:

Test sur Chrome dernier, tout était délitable. delete fonction retournée true pour toutes les méthodes suivantes, et les a effectivement supprimées:

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
2017-11-23 10:36



Les variables, contrairement aux propriétés simples, ont un attribut [[Configurable]], ce qui signifie impossibilité de supprimer une variable via le effacer opérateur. Cependant, il existe un contexte d'exécution sur lequel cette règle n'affecte pas. C'est le eval context: l'attribut [[Configurable]] n'est pas défini pour les variables.


2
2018-01-25 04:46



Vous ne pouvez pas supprimer une variable si vous l'avez déclarée (avec var x;) au moment de la première utilisation. Cependant, si votre variable x apparaît pour la première fois dans le script sans déclaration, vous pouvez utiliser l'opérateur de suppression (delete x;) et votre variable sera supprimée, très similaire à la suppression d'un élément d'un tableau ou à la suppression d'une propriété .


1
2018-03-31 17:48