Побит рекорд самого короткого кода по определению IE
Без малого год назад, я уже писал (http://habrahabr.ru/blogs/javascript/50544/) о самом коротком способе определение браузера Internet Explorer, но вот некто Aleko нашел еще более короткий вариант:
-[1,]
Всего 5 байт. Пример использования: if(-[1,]){
alert("Not IE!");
}
А для тех кто не силён в яваскрипте, это как бы и не имеет особой силы =)
В описанном выше примере сообщение «Not IE!» появится только в случае… если броузер не IE.
Я так дума, что просто IE считает, что после «1» в массиве должен быть еще один элемент, ибо стоит запятая. А его нет.
Другие браузеры не обращают внимания, а он — спотыкается.
Нет, не так. Во первых IE не «спотыкается» на запятой, а считает её признаком ещё одного элемента, не более. Во вторых конструкция
{name1:val1,name2:val2,}
выдаст ошибку не из за запятой а из за того что в хэше, где используется сочетание ключ: значение в отличие от массивов, не будет найден очередной ключ.
Обычные браузеры при таком определении решат, что это число и получат "-1", а ИЕ — нет, поэтому он не сможет применить операцию "-". Как-то так, а по ссылке в посте все подробно расписано.
Если я не забыл все напрочь, для объекта-массива в таких случаях вызывается toString, который возвращает строку «1», которая конвертируется в число 1 для алгебраических операций. Вроде так. Гуру меня поправят.
Фишка в запятой после последнего элемента массива. По стандарту ECMAscript, одна запятая в конце игнорируется — это сделано для удобства записи в столбик, автогенерации и прочего. В Internet Explorer эта запятая добавляет пустой элемент. Итого во всех браузерах кроме internet explorer получится массив из одного числа. Минус перед массивом преобразует его в число. Массив из двух элементов, получившийся у Internet Explorer, в число не преобразуется, результатом будет значение «NaN», которое в условии «if» считается за «false». У всех остальных браузеров получится -1, которая считается за «true». Вот такие вот забавные документированные баги. Почему не убрали — непонятно :(.
Здесь дело не в стандартах. В IE используется Jscript, в FF и Webkit — Javascript и только в Opera — ECMAscript. Так что если говорить про стандарты, то кроме Opera никто их не поддерживает.
> Вот такие вот забавные документированные баги. Почему не убрали — непонятно :(.
Не убрали, чтобы самим быстро определять где же они, пользователи ИЕ :)
Ну почему же? Вполне стандартная политика Микрософта, заключается в следовании подходу «работает — не трожь». То есть вместо переписывания бажного куска они просто предлагают альтернативный вариант решения.
Для обратной совместимости это хорошо, а вот в конечном счете для разработчиков системы это плоховато. Впрочем они обычно в случае, когда багов и хитроумных способов их обойти становится слишком много, просто предлагают перейти на новую технологию и начать с чистого листа.
Поясняю: «Массив из двух элементов, получившийся у Internet Explorer, в число не преобразуется» потому как при развертывании в IE мы получим не 1 а 1 с запятой, так как будет иметь место перечисление элементов — единицы и второго, несуществующего.
ну практически соглашусь… в 99% случаев требуется отличать какая именно версия ИЕ… а не то что это ИЕ вообще…
да и экономия в один байт… нет я понимаю — сам программирую уже довольно давно… сидел и на 286-х и на спектруме — но при современных скоростях чтения-записи, объёмах винтов и памяти и ширинах каналов это капля в море.
даже не просьба, скорее напоминание… если вам понравился коммент — плюсаните и в карму: это очень поможет тем, кто оказался не удел из-за одного неудачного топика.
с одной стороны гениально. с другой, если завтра js в webkit или mozilla вдруг начнёт вести себя аналогичным образом, придётся всё переделывать. так что гениальность сродни баяну
function getTomorrowDate() { sleep(86400); return strftime("%D"); }
Не начнут. Только MS нарушает стандарт ECMA (видимо, по историческим причинам — их реализация появилась еще до того, как стандарт устоялся, а «родная» совместимость дороже:). Скорее наоборот — IE9 или IE16 какой-нибудь могут начать приводить массивы по стандарту. Но тогда есть надежда, что и в остальном они будут вести себя как положено и отделять код для них и не понадобится…
Проверки основанные на ошибках, оригинально. К хорошему это не приводит. А на других, более серьезных языках автор данного варианта также программирует? Вот что интересно:-) Во многих компаниях за варнинги уже по голове не гладят, а тут такое. Да и почему только IE, многие вещи к примеру могут заработать во всех кроме FireFox или Opera, а бывают моменты, что для каждого браузера своя реализация нужна и куча подобных багов браузеров снесет башню новому программисту, которому придется курить код.
А в какой версии Opera выдавались предупреждения? Я проверял в 9 (кажется финальной девятой) и 10 версиях — хак не вызывал никаких отрицательных эмоций у браузера )
Очень может быть, так как майкрософтовцы обещали сильно переписанный js движок в 9 IE, так что остается надеяться на то, что именно такие устоявшиеся безобидные помарки останутся.
На то, что движок допилят до такой степени соответствия стандартам, что отводить для него отдельную ветку кода просто не понадобится, надежды уже нет? :)
Кстати, обсуждение этой «фичи» (про добавление пустого элемента) было уже на хабре, странно, что только сейчас способ определения ИЕ через него придумали habrahabr.ru/blogs/javascript/67567/
То же самое, что определять марку машины вслепую по шершавости покрытия выхлопной трубы. Руки отрывать таким «умельцам». Есть штатные средства для определения, чем не устраивают?
Не устраивают штатные средства как раз тем, что они штатные (и зачастую очень уж некомпактные). Писать такие хаки — спорт и искусство. Мне это доставляет удовольствие.
Я предпочитаю скрипт для IE грузить на уровне заголовка страницы.
Если IE — грузим ie.js
ИМХО — так проще…
Зачем другим браузерам вообще парсить и грузить код, который нужен експлореру?
хотя определение — зачетное… правда прослужит ли оно в новых експлорерах?
комментарии (76)
В описанном выше примере сообщение «Not IE!» появится только в случае… если броузер не IE.
-[1,] — механизм вот этой штуки поясните и все.
Другие браузеры не обращают внимания, а он — спотыкается.
{name1:val1,name2:val2,}
{name1:val1,name2:val2,}
выдаст ошибку не из за запятой а из за того что в хэше, где используется сочетание ключ: значение в отличие от массивов, не будет найден очередной ключ.
В противном случае единственный элемент массива преобразуется в число и мы получаем -1, что в условии проходит.
Не убрали, чтобы самим быстро определять где же они, пользователи ИЕ :)
Для обратной совместимости это хорошо, а вот в конечном счете для разработчиков системы это плоховато. Впрочем они обычно в случае, когда багов и хитроумных способов их обойти становится слишком много, просто предлагают перейти на новую технологию и начать с чистого листа.
да и экономия в один байт… нет я понимаю — сам программирую уже довольно давно… сидел и на 286-х и на спектруме — но при современных скоростях чтения-записи, объёмах винтов и памяти и ширинах каналов это капля в море.
В Опере есть возможность «Представиться как IE Explorer». Звучит как «Прикинуться дурачком»
тоже самое и с кармой)
и вправду цитаты #97364 на bash.org.ru нету ;-)
)
govnokod.ru/258
function getTomorrowDate() { sleep(86400); return strftime("%D"); }
if('\v' == 'v') { // IE
…
}
habrahabr.ru/blogs/javascript/67567/
Если IE — грузим ie.js
ИМХО — так проще…
Зачем другим браузерам вообще парсить и грузить код, который нужен експлореру?
хотя определение — зачетное… правда прослужит ли оно в новых експлорерах?
не короткий, но голову можно сломать :)