Why is document.all defined, but typeof document.all returns "undefined"?

I did some research on JavaScript typeof , and came across the following oddity:

Exceptions

All current browsers expose a non-standard document.all host object of type Undefined.

 typeof document.all === 'undefined'; 

Although the specification allows you to create custom type tags for non-standard exotic objects, they require type tags other than predefined ones. The case of document.all having a tag of type 'undefined' should be classified as an exceptional violation of the rules.

( Source )

I installed the following in my browser to check it out:

 console.log("typeof: " + typeof document.all); console.log("toString: " + document.all); 

It gave:

 typeof: undefined toString: [object HTMLAllCollection] 

So why is document.all like this? Since document.all is an object (defined in my browser), shouldn't typeof return "object" and not "undefined" ?

+6
source share
2 answers

Take a look at this from the HTML Spec

The all attribute should return the HTMLAllCollection embedded in the Document node, the filter of which matches all elements.

The object returned for all has several unusual actions:

  • The user agent should act as if the abstract ToBoolean operation in JavaScript returned false when the object returned for all was specified.

  • The user agent must act as if the abstract equality comparison algorithm were used when the object returned for all specified, returns true when compared to undefined and null . (Comparison using a strict equality comparison algorithm and abstract equality comparison with other values, such as strings or objects, not affected.)

  • The user agent must act so that the typeof operator in JavaScript returns the string "undefined" when applied to the returned all object.

The third case is yours.

The rationale for this is compatibility with code developed for older browsers, as explained in a note in the specification:

This violation is motivated by the desire for compatibility with two classes of obsolete content: one that uses the presence of document.all as a way to detect obsolete user agents, and one that only supports these obsolete user agents and uses the document.all object without testing to be present in the first turn.

Hope this makes sense to you.

+6
source

Workaround update:

 document.all !== undefined; >> true /*otherwise*/ false 

Since https://html.spec.whatwg.org/ requires that ...

The user agent must act as if the abstract equality comparison algorithm was used when returning the object returned for all, returns true compared to undefined and null values.

but since ...

(Comparison using the strict equality comparison algorithm and comparing abstract equality with other values, such as strings or objects, is not affected .)

using the Static Type Comparison Operator (for example: === |! == ) it is completely safe to check whether the HTMLAllCollection object can be used and / or present in the current UA client.

The Dynamic Type Comparison Operator will continue to return a false absence, as required by the specification.

 document.all != undefined; >> false /*otherwise*/ false 

Workaround (older)

 "all" in document; >> true /*otherwise*/ false 

A more complex approach when working with third-party code will be

 delete document.all && "all" in document >> true /*otherwise*/ false 
0
source

Source: https://habr.com/ru/post/1012387/


All Articles