Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is document.all defined but typeof document.all returns "undefined"? [duplicate]

Tags:

javascript

dom

I was doing some research on JavaScript's typeof operator, and stumbled across the following weirdness:

Exceptions

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

typeof document.all === 'undefined';

Although the specification allows custom type tags for non-standard exotic objects, it requires those type tags to be different from the predefined ones. The case of document.all having type tag 'undefined' must be classified as an exceptional violation of the rules.

(Source)

I set up the following in my browser to test it:

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

It yielded:

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", not "undefined"?

like image 851
Nissa Avatar asked Nov 16 '16 22:11

Nissa


1 Answers

Take a look at this one from Html Spec

The all attribute must return an HTMLAllCollection rooted at the Document node, whose filter matches all elements.

The object returned for all has several unusual behaviors:

  1. The user agent must act as if the ToBoolean abstract operation in JavaScript returns false when given the object returned for all.

  2. The user agent must act as if the Abstract Equality Comparison algorithm, when given the object returned for all, returns true when compared to the undefined and null values. (Comparisons using the Strict Equality Comparison algorithm, and Abstract Equality comparisons to other values such as strings or objects, are unaffected.)

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

The third case is yours.

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

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

Hope it will make sense for you.

like image 154
The Reason Avatar answered Oct 24 '22 11:10

The Reason