Почему null и undefined типа DOMWindow?
Когда вы запустите следующий код в браузере или в Node.js, вы получите ожидаемые результаты, перечисленные в комментариях:
Object.prototype.toString.call(undefined); // "[object Undefined]"
Object.prototype.toString.call(null); // "[object Null]"
Однако, когда вы запускаете этот код в PhantomJS, в обоих случаях вывод [object DOMWindow]
.
Это кажется странным, поскольку undefined
и null
являются общими типами. Оператор typeof
работает так же, как и в других средах (включая typeof null === "object"
quirk), поэтому, по-видимому, PhantomJS, по крайней мере, имеет концепцию типа undefined:
typeof undefined; // "undefined"
Он также утверждает, что Object.prototype.toString
содержит собственный код, который может указывать на то, что Phantom сам ничего не делает для изменения реализации (я не знаю, если это случай или нет, хотя - я не был может найти что-нибудь полезное в источнике):
Object.prototype.toString.toString(); // "function toString() { [native code] }"
Итак, почему PhantomJS не использует (или хотя бы выставляет) правильные значения свойств [[Class]]
для null
и undefined
, и есть ли способ изменить это? Я знаю, что я мог бы использовать другой метод для определения типа, но мне бы этого не хотелось.
Ответы
Ответ 1
Это комбинация двух вещей. A script выполняется на веб-странице, поэтому глобальный объект является объектом window
, о чем свидетельствует:
console.log(this.toString()); // [object DOMWindow]
Кроме того, существует проблема с той версией реализации JavaScript, которая фальсифицирует цепочку прототипов объекта в вышеуказанном условии.
Скорее всего, это будет исправлено в какой-то будущей версии.
Ответ 2
Я признаю, что я добираюсь сюда, но статья в MDN на Object.toString()
упоминает:
Начиная с JavaScript 1.8.5 toString(), вызванного null возвращает [object Null], а undefined возвращает [object Undefined], как определено в пятом выпуске ECMAScript и последующих исправлениях. См. Использование toString для определения типа объекта.
Затем связанный раздел описывает конструкцию Object.prototype.toString(null)
, которую вы используете. Таким образом, кажется, что мы можем разумно подчёркивать null
, а undefined
- это новое (-ish) дополнение/исправление к Javascript, которое движок PhantomJS (Apple JavaScriptCore, у которого неизвестно, какая версия) еще не реализована. Тем не менее, это правильно работает в Safari 6, поэтому, возможно, стоит сообщить об этом как об ошибке, требуя соблюдения ES5.
Ответ 3
Если это всего лишь 2 типа, я думаю, вы можете просто окружить свою проблему этим.
Object.prototype.toString = function(obj){
if(typeof(obj) == "undefined"){
return "[object Undefined]";
}
if(typeof(obj) == "null"){
return "[object Null]";
}
return obj.toString();
}