validate - validar variables indefinidas javascript
¿Los elementos del árbol DOM con identificadores se convierten en variables globales? (4)
Como se mencionó en la respuesta anterior, este comportamiento se conoce como acceso con nombre en el objeto de la ventana . El valor del atributo de name
para algunos elementos y el valor del atributo de id
para todos los elementos están disponibles como propiedades del objeto de window
global. Estos son conocidos como elementos nombrados. Dado que la window
es el objeto global en el navegador, cada elemento nombrado será accesible como una variable global.
Esto fue originalmente agregado por Internet Explorer y finalmente fue implementado por todos los demás navegadores simplemente por compatibilidad con los sitios que dependen de este comportamiento. Curiosamente, Gecko (el motor de renderizado de Firefox) optó por implementar esto solo en modo peculiar , mientras que otros motores de renderización lo dejaron activado en modo estándar.
Sin embargo, a partir de Firefox 14, Firefox ahora también admite el acceso con nombre en el objeto de window
en modo estándar. ¿Por qué cambiaron esto? Resulta que todavía hay muchos sitios que confían en esta funcionalidad en modo estándar. Microsoft incluso lanzó una demostración de marketing que lo hizo, evitando que la demostración funcionara en Firefox.
Webkit ha considerado recientemente lo contrario , relegando el acceso con nombre en el objeto de la window
a modo de caprichos solamente. Decidieron no hacerlo por el mismo razonamiento que Gecko.
Así que ... por loco que parezca, este comportamiento ahora es técnicamente seguro de usar en la última versión de todos los principales navegadores en modo estándar . Pero si bien el acceso con nombre puede parecer algo conveniente, no debe utilizarse .
¿Por qué? Gran parte del razonamiento se puede resumir en este artículo sobre por qué las variables globales son malas . En pocas palabras, tener un montón de variables globales adicionales conduce a más errores. Digamos que accidentalmente escribes el nombre de una var
y pasas a escribir una id
de un nodo DOM, ¡SORPRESA!
Además, a pesar de estar estandarizado, todavía hay algunas discrepancias en las implementaciones de los navegadores de acceso con nombre.
- IE hace incorrectamente que el valor del atributo de
name
accesible para los elementos del formulario (entrada, selección, etc.). - Gecko y Webkit NO hacen que las etiquetas
<a>
sean accesibles a través de su atributo dename
. - Gecko maneja incorrectamente múltiples elementos con nombre con el mismo nombre (devuelve una referencia a un solo nodo en lugar de una matriz de referencias).
Y estoy seguro de que hay más si intenta usar el acceso con nombre en los casos perimetrales.
Como se mencionó en otras respuestas, use document.getElementById
para obtener una referencia a un nodo DOM por su id
. Si necesita obtener una referencia a un nodo por su atributo de name
use document.querySelectorAll
.
Por favor, no propague este problema utilizando el acceso con nombre en su sitio. Muchos desarrolladores web han perdido el tiempo intentando rastrear este comportamiento mágico . Realmente necesitamos actuar y hacer que los motores de renderización desactiven el acceso con nombre en el modo estándar. A corto plazo, romperá algunos sitios haciendo cosas malas, pero a la larga ayudará a que la web avance.
Si está interesado, hablo de esto con más detalle en mi blog: https://www.tjvantoll.com/2012/07/19/dom-element-references-as-global-variables/ .
Trabajando en una idea para un envoltorio HTMLElement simple, me topé con lo siguiente para Internet Explorer y Chrome :
Para un HTMLElement con ID en el árbol DOM, es posible recuperar el div usando su ID como el nombre de la variable. Así que para un div como
<div id="example">some text</div>
En Internet Explorer 8 y Chrome puedes hacer:
alert(example.innerHTML); //=> ''some text''
o
alert(window[''example''].innerHTML); //=> ''some text''
Entonces, ¿significa esto que cada elemento en el árbol DOM se convierte en una variable en el espacio de nombres global? ¿Y también significa que uno puede usar esto como un reemplazo para el método getElementById
en estos navegadores?
Debes atenerse a getElementById()
en estos casos, por ejemplo:
document.getElementById(''example'').innerHTML
A IE le gusta mezclar elementos con los atributos de name
e ID
en el espacio de nombres global, por lo que es mejor ser explícito sobre lo que está tratando de obtener.
Lo que se supone que sucede es que los "elementos con nombre" se agregan como propiedades aparentes del objeto de document
. Esta es una idea realmente mala, ya que permite que los nombres de los elementos entren en conflicto con las propiedades reales del document
.
IE empeoró la situación al agregar también elementos con nombre como propiedades del objeto de window
. Esto es doblemente malo ya que ahora debe evitar nombrar sus elementos después de que cualquier miembro del document
o el objeto de la window
que usted (o cualquier otro código de biblioteca en su proyecto) pueda querer usar.
También significa que estos elementos son visibles como variables de tipo global. Por suerte, en este caso, cualquier declaración de var
o function
global real en su código los sombrea, por lo que no tiene que preocuparse tanto por nombrar aquí, pero si intenta hacer una asignación a una variable global con un nombre en conflicto y olvida para declararlo var
, obtendrá un error en IE al intentar asignar el valor al elemento en sí.
En general, se considera una mala práctica omitir var
, así como confiar en que los elementos con nombre sean visibles en la window
o como elementos globales. Apégate a document.getElementById
, que es más compatible y menos ambiguo. Puede escribir una función de envoltura trivial con un nombre más corto si no le gusta la escritura. De cualquier manera, no tiene sentido usar un caché de búsqueda de id-a-elemento, porque los navegadores generalmente optimizan la llamada getElementById
para usar una búsqueda rápida de todos modos; todo lo que obtiene son problemas cuando los elementos cambian de id
o se agregan / eliminan del documento.
Opera copió el IE, luego se unió a WebKit, y ahora tanto la práctica no estandarizada de poner elementos con nombre en las propiedades del document
como la práctica de ponerlos en la window
se being standardised mediante HTML5, cuyo enfoque es documentar y estandarice cada práctica terrible que nos infligen los autores de los navegadores, haciéndolos parte de la web para siempre. Así que Firefox 4 también soportará esto.
¿Qué son los ''elementos nombrados''? Cualquier cosa con un id
, y cualquier cosa con un name
se use para propósitos de "identificación": es decir, formas, imágenes, anclas y algunos otros, pero no otras instancias no relacionadas de un atributo de name
, como los nombres de control en los campos de entrada de formulario, nombres de parámetros en <param>
o metadatos tipo en <meta>
. Los name
''identificación'' son los que deben evitarse en favor de id
.
Ellos si.
Probado en Chrome 55, Firefox 50, IE 11, IE Edge 14 y Safari 10
con el siguiente ejemplo:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<div id="im_not_particularly_happy_with_that">
Hello World!
</div>
<script>
im_not_particularly_happy_with_that.innerText = ''Hello Internet!'';
</script>
<!-- Looking at you W3 HTML5 spec group ಠ_ಠ -->
</body>
</html>