Все объекты в JavaScript являются правдивыми по спецификации, но в DOM один не примитивный объект не является. Который?

этот твит в Twitter:

В JavaScript все объекты являются правдивыми (согласно спецификации). В DOM существует одно исключение из этого правила. Что это? #jsquiz #fronttrends

Кто-нибудь знает ответ?

Ответы

Ответ 1

Отказ от ответственности: Я тот парень, который чирикал::) Это был вопрос, который я задавал бы и отвечал бы в своем Front-Trends. Я написал этот твит за 5 минут до выхода на сцену.


Из-за ограничения на 140 символов в Twitter, вопрос немного неоднозначен. Реальный вопрос, который я задавал, заключается в следующем.

Спецификация ECMAScript определяет ToBoolean() следующим образом:

ToBoolean(condition), slide from my Front-Trends 2012 talk

Как вы можете видеть, все непримитивные объекты (т.е. все объекты, которые являются логическими, число, строка, undefined или null), являются правдивыми по спецификации. Однако в DOM есть одно исключение - объект DOM, который является ложным. Вы знаете, какой из них? Ответ: document.all. Спецификация HTML говорит:

Атрибут all должен вернуть HTMLAllCollection, внедренный в Document node, фильтр которого соответствует всем элементам.

Объект, возвращенный для всех, имеет несколько необычных типов поведения:

Пользовательский агент должен действовать так, как если бы оператор ToBoolean() в JavaScript преобразует возвращаемый объект для all в значение false.

Пользовательский агент должен действовать так, как будто для == и !=операторов в JavaScript, объект, возвращаемый для all, равен undefined.

Пользовательский агент должен действовать так, что оператор typeof в JavaScript возвращает строку 'undefined' при применении к возвращенному объекту all.

Эти требования являются преднамеренным нарушением JavaScript спецификация тока на момент написания (ECMAScript edition 5). Спецификация JavaScript требует, чтобы оператор ToBoolean()конвертировать все объекты в значение true и не имеет положений для объектов, действующих, как если бы они были undefined для целей некоторые операторы. Это нарушение мотивировано желанием совместимость с двумя классами устаревшего контента: тот, который использует наличие document.all в качестве способа обнаружения устаревших пользовательских агентов и который поддерживает только те устаревшие пользовательские агенты и использует document.all объект без тестирования для его присутствия в первую очередь.

Итак, document.all является единственным официальным исключением из этого правила ECMAScript. (В Opera, document.attachEvent и т.д. Тоже ложны, но это нигде не указано.)

Ответ 2

Это document.all.

Это нестандартное, поэтому вам лучше использовать document.getElementsByTagName("*").

Ответ 3

Хорошо, используя этот код

for (var name in document) {
    if (!!document[name] === false && typeof document[name] === 'object' && document.hasOwnProperty(name)) {
        $('#foo').append('document.' + name + '<br />');        
    };
};​

У меня был этот результат в хроме (результаты могут отличаться)

document.ownerDocument
document.attributes
document.namespaceURI
document.nextSibling
document.webkitCurrentFullScreenElement
document.nodeValue
document.preferredStylesheetSet
document.textContent
document.previousSibling
document.parentNode
document.xmlVersion
document.parentElement
document.localName
document.selectedStylesheetSet
document.prefix
document.xmlEncoding

Ответ 4

Просто перетащите документ и проверьте все.

http://jsfiddle.net/UTNkW/3/

EDIT: неправильная методология тестирования, к счастью, кто-то указал на это, и я мог бы исправить это.