w3schools variable tag tab error change javascript global-variables undefined

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

  1. 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ón var , que queda donde es. Por lo tanto, en el siguiente código, a es una referencia de VariableEnvironment y no la propiedad de la window y su valor será 10 al final del código:

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

  2. 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.



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;