variable - undefined javascript error
¿Cómo desarmar una variable de JavaScript? (10)
Tengo una variable global en JavaScript (en realidad una propiedad de window
, pero no creo que importe) que ya estaba poblada por una secuencia de comandos anterior, pero no quiero otra secuencia de comandos que se ejecute más tarde para ver su valor o que fue incluso definido.
He puesto some_var = undefined
y funciona con el propósito de probar typeof some_var == "undefined"
pero realmente no creo que sea la forma correcta de hacerlo.
¿Qué piensas?
Además de lo que todos han escrito, también tenga en cuenta que delete
devuelve booleano. Puede decirle si la eliminación fue exitosa o no.
ACTUALIZAR:
Probando en el último Chrome, todo fue eliminable. delete
función de delete
volvió true
para todos los métodos siguientes, y en realidad los eliminó:
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
ECMAScript 2015 ofrece Reflect API. Es posible eliminar la propiedad del objeto con Reflect.deleteProperty() :
Reflect.deleteProperty(myObject, ''myProp'');
// it is equivalent to:
delete myObject.myProp;
delete myObject[''myProp''];
Para eliminar la propiedad del objeto de window
global:
Reflect.deleteProperty(window, ''some_var'');
En algunos casos, las propiedades no se pueden eliminar (cuando la propiedad no es configurable) y luego esta función devuelve false
(así como el operador de eliminación ). En otros casos devuelve 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
Hay una diferencia entre la función deleteProperty
y el operador delete
cuando se ejecuta en modo estricto:
''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
El operador de delete
elimina una propiedad de un objeto. No se puede eliminar una variable. Entonces, la respuesta a la pregunta depende de cómo se define la variable o propiedad global.
(1) Si se crea con var
, no se puede eliminar.
Por ejemplo:
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) Si se crea sin var
, se puede eliminar.
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
Explicacion tecnica
1. Usando var
En este caso, la referencia g_a
se crea en lo que la especificación ECMAScript llama " VariableEnvironment " que se adjunta al alcance actual. Este puede ser el contexto de ejecución de una función en el caso de usar var
dentro de una función (aunque puede ser un poco más complicado cuando se considera let
) o en el caso del código "global", el VariableEnvironment se adjunta al objeto global (a menudo window
).
Las referencias en VariableEnvironment normalmente no se pueden eliminar: el proceso detallado en ECMAScript 10.5 explica esto en detalle, pero es suficiente para decir que a menos que su código se ejecute en un contexto eval
(que utilizan la mayoría de las consolas de desarrollo basadas en navegador), las variables declaradas con var
no se puede eliminar.
2. Sin usar var
Cuando se trata de asignar un valor a un nombre sin usar la palabra clave var
, Javascript intenta ubicar la referencia mencionada en lo que la especificación ECMAScript llama " VariableEnvironment ", y la principal diferencia es que LexicalEvironment s están anidados, es decir, LexicalEnvironment tiene un padre (lo que la especificación de ECMAScript llama "referencia de entorno externo") y cuando Javscript no puede ubicar la referencia en un LexicalEenvironment , busca en el LexicalEnvironment primario (como se detalla en 10.3.1 y 10.2.2.1 ). El nivel superior de LexicalEnvironment es el " entorno global ", y está vinculado al objeto global en el sentido de que sus referencias son las propiedades del objeto global. Por lo tanto, si intenta acceder a un nombre que no se declaró utilizando una palabra clave var
en el ámbito actual o en cualquier ámbito externo, Javascript finalmente buscará una propiedad del objeto de window
para que sirva de referencia. Como hemos aprendido anteriormente, las propiedades de los objetos se pueden eliminar.
Notas
Es importante recordar que las declaraciones
var
están "elevadas", es decir, siempre se considera que sucedieron al principio del alcance en el que se encuentran, aunque no es la inicialización del valor que se puede hacer en una declaraciónvar
, que queda donde es. Por lo tanto, en el siguiente código,a
es una referencia de VariableEnvironment y no la propiedad de lawindow
y su valor será10
al final del código:function test() { a = 5; var a = 10; }
La discusión anterior es cuando "modo estricto" no está habilitado. Las reglas de búsqueda son un poco diferentes cuando se usa el "modo estricto" y las referencias léxicas que se habrían resuelto en las propiedades de la ventana sin el "modo estricto" generarán errores de "variable no declarada" en el "modo estricto". Realmente no entendí dónde se especifica esto, pero es cómo se comportan los navegadores.
El operador de eliminación elimina una propiedad de un objeto.
delete object.property
delete object[''property'']
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete
De acuerdo a la pregunta necesitas uno de los siguientes.
delete some_var;
delete window.some_var;
delete window[''some_var''];
La respuesta de @ scunlife funcionará, pero técnicamente debería ser
delete window.some_var;
se supone que eliminar es un no-op cuando el destino no es una propiedad de objeto. p.ej,
(function() {
var foo = 123;
delete foo; // wont do anything, foo is still 123
var bar = { foo: 123 };
delete bar.foo; // foo is gone
}());
Pero como las variables globales son en realidad miembros del objeto de ventana, funciona.
Cuando se involucran cadenas de prototipos, el uso de la eliminación se vuelve más complejo porque solo elimina la propiedad del objeto de destino y no el prototipo. p.ej,
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.
Así que ten cuidado.
EDITAR: Mi respuesta es algo inexacta (vea "Conceptos erróneos" al final). El enlace explica todos los detalles sangrientos, pero el resumen es que puede haber grandes diferencias entre los navegadores y en función del objeto del que se está eliminando. delete object.someProp
generalmente debería ser seguro siempre que object !== window
. Todavía no lo usaría para eliminar variables declaradas con var
aunque puede hacerlo en las circunstancias adecuadas.
Las variables, en contraste con las propiedades simples, tienen el atributo [[Configurable]] , lo que significa la imposibilidad de eliminar una variable a través del operador de eliminación . Sin embargo, hay un contexto de ejecución en el que esta regla no afecta. Es el contexto eval : el atributo [[Configurable]] no está configurado para las variables.
No puede eliminar una variable si la declaró (con var x;) en el momento del primer uso. Sin embargo, si su variable x apareció por primera vez en el script sin una declaración, entonces puede usar el operador de eliminación (delete x;) y su variable será eliminada, muy similar a la eliminación de un elemento de una matriz o la eliminación de una propiedad de un objeto .
Si está declarando implícitamente la variable sin var
, la forma correcta sería usar delete foo
.
Sin embargo, después de eliminarlo, si intenta usar esto en una operación como la adición, se lanzará un ReferenceError
porque no puede agregar una cadena a un identificador no declarado no declarado. Ejemplo:
x = 5;
delete x
alert(''foo'' + x )
// ReferenceError: x is not defined
Puede ser más seguro en algunas situaciones asignarlo a falso, nulo o indefinido para que se declare y no genere este tipo de error.
foo = false
Tenga en cuenta que en ECMAScript null
, false
, undefined
, 0
, NaN
o ''''
todos se evaluarían como false
. Solo asegúrate de no usar el operador !==
sino que, en su lugar !=
cuando se escribe booleanos y no quieres verificar la identidad (por lo tanto, null
sería == false
y false == undefined
).
También tenga en cuenta que delete
no "elimina" las referencias, sino solo las propiedades directamente en el objeto, por ejemplo:
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 ha declarado una variable con var
no puede eliminarla:
(function() {
var x = 5;
alert(delete x)
// false
})();
En Rhino:
js> var x
js> delete x
false
Tampoco puedes eliminar algunas propiedades predefinidas como Math.PI
:
js> delete Math.PI
false
Hay algunas excepciones extrañas para delete
como con cualquier idioma, si te importa lo suficiente, debes leer:
TLDR: las variables definidas simples (sin var
, let
, const
) podrían eliminarse con delete
. Si usa var
, let
, const
, no se pudieron eliminar ni con delete
ni con 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 muestra el mismo comportamiento.
some_var = null;
//or remove it..
delete some_var;