solucionar falsy como javascript dom

falsy - javascript void 0 como solucionar



¿Por qué document.all falsy? (4)

document.all es un objeto no primitivo en el DOM que es falso.

Por ejemplo, este código no hace nada:

if (document.all) { alert("hello"); }

¿Alguien puede explicar por qué es esto?


En resumen, es para que AMBAS de estas muestras de código funcionen. Los navegadores deben hacer esto para que las páginas web antiguas continúen funcionando.

Muestra 1

// Internet Explorer if (document.all) { useActiveX() } // Netscape Navigator else { useOldButStillWorkingCode() }

Muestra 2

document.all.output.innerHTML = ''Hello, world!''


Los navegadores modernos ya no implementan esta cosa desactualizada. Fue presentado por IE, pero la mayoría de los otros lo "calza" para que sea compatible.

Para hacer posible la detección de navegadores (en los viejos tiempos se podía diferenciar a IE de NN probando document.all ) mientras se soportaba la sintaxis de document.all, otros navegadores realizaban la implementación "extraña" que typeof document.all devuelve indefinido.

Opera> document.all // prints the array-like object Opera> typeof document.all "undefined" Opera> Boolean(document.all) false

Antes de que FF dejara de apoyarlo, también mostró un comportamiento extraño como se indica en este mensaje . Puede encontrar más elementos internos en el error # 412247 de Mozilla .

También hay un hilo muy largo en el archivo de la lista de correo del W3C, que comienza con http://lists.w3.org/Archives/Public/public-html/2009Jun/0546.html



Descargo de responsabilidad: Soy el tipo que tuiteó la pregunta que condujo a este hilo :) Era una pregunta que haría y respondería en mi charla de Front-Trends . Escribí ese tuit 5 minutos antes de subir al escenario.

La pregunta que estaba haciendo es la siguiente.

La especificación de ECMAScript define ToBoolean() siguiente manera :

Como puede ver, todos los objetos no primitivos (es decir, todos los objetos que no son booleanos, un número, una cadena, undefined o null ) son verdaderos según la especificación. Sin embargo, en el DOM, hay una excepción a esto: un objeto DOM que es falso. ¿Sabes cuál es?

La respuesta es document.all . La especificación de HTML dice:

El atributo all debe devolver una HTMLAllCollection enraizada en el nodo Document , cuyo filtro coincide con todos los elementos.

El objeto devuelto para todos tiene varios comportamientos inusuales:

El agente de usuario debe actuar como si el operador ToBoolean() en JavaScript convierte el objeto devuelto para all en el valor false .

El agente de usuario debe actuar como si, a los efectos de los operadores == y != En JavaScript, el objeto devuelto para all es igual al valor undefined .

El agente de usuario debe actuar de tal manera que el operador typeof en JavaScript devuelva la cadena ''undefined'' cuando se aplica al objeto devuelto para all .

Estos requisitos son una violación voluntaria de la especificación de JavaScript vigente en el momento de la escritura (ECMAScript edición 5). La especificación JavaScript requiere que el operador ToBoolean() convierta todos los objetos al valor true , y no tiene disposiciones para objetos que actúan como si no estuvieran undefined para los propósitos de ciertos operadores. Esta infracción está motivada por el deseo de compatibilidad con dos clases de contenido heredado: uno que utiliza la presencia de document.all como una forma de detectar agentes de usuario heredados, y uno que solo admite esos agentes de usuario heredados y utiliza el objeto document.all sin probar primero su presencia.

Entonces, document.all es la única excepción oficial a esta regla de ECMAScript. (En Opera, document.attachEvent , etc. también son falsas, pero eso no se especifica en ninguna parte).

El texto anterior explica por qué se hizo esto. Pero aquí hay un fragmento de código de ejemplo que es muy común en páginas web antiguas, y eso lo ilustrará más a fondo:

if (document.all) { // code that uses `document.all`, for ancient browsers } else if (document.getElementById) { // code that uses `document.getElementById`, for “modern” browsers }

Básicamente, para un document.all mucho tiempo. document.all se usó de esta manera para detectar navegadores antiguos. Sin embargo, dado que document.all se prueba primero, los navegadores más modernos que ofrecen ambas propiedades seguirán apareciendo en la ruta del document.all . En los navegadores modernos, preferiríamos usar document.getElementById , por supuesto, pero como la mayoría de los navegadores aún tienen document.all (por otras razones de compatibilidad con versiones anteriores), nunca se accederá a los else si document.all fuera cierto. Si el código se hubiera escrito de manera diferente, esto no sería un problema:

if (document.getElementById) { // code that uses `document.getElementById`, for “modern” browsers } else if (document.all) { // code that uses `document.all`, for ancient browsers }

Pero lamentablemente, muchos códigos existentes lo hacen al revés.

La solución más simple para este problema es simplemente hacer que document.all sea ​​falso en los navegadores que aún lo imitan.