Comments 122
typeof null; // object
null === Object; // false
на мой взгляд логично
null === Object; // false
на мой взгляд логично
+16
Необычное поведение NaN — требование IEEE 754, общее для всех языков программирования.
+34
Чтобы типу Number можно было присвоить NaN.
+2
Чтобы NaN не был равен ничему другому.
+10
Чтобы не возникало ошибки, когда математическая операция возвращает неизвестно что, например при делении нуля на ноль, интерпретатор по стандарту должен возвращать NaN.
+6
Infinity === 1/0 // true
то ли Infinity === NaN, то ли 1/0 у них *равно* бесконечности.
то ли Infinity === NaN, то ли 1/0 у них *равно* бесконечности.
-5
NaN'у ничего не может быть ни равно ни эквивалентно
0
деление на 0 в математическом смысле на самом деле бесконечное число
NaN получается в арифметических операциях, которые либо ошибочны (деление на строку), либо второе =) мало ли что могут сделать со знаком "+"
NaN получается в арифметических операциях, которые либо ошибочны (деление на строку), либо второе =) мало ли что могут сделать со знаком "+"
0
0/0 даёт NaN — это неопределённая операция.
1/0 даёт бесконечность — это общепринято в математике.
1/0 даёт бесконечность — это общепринято в математике.
+3
UFO just landed and posted this here
Java:
public final class Double
…
public static boolean isNaN(double v) {
return (v != v);
}
…
}
всё правильно =)
public final class Double
…
public static boolean isNaN(double v) {
return (v != v);
}
…
}
всё правильно =)
+3
Насчёт критики этого требования стандарта и объяснения почему автор топика имеет право возмущатся по этому поводу:
bertrandmeyer.com/2010/02/06/reflexivity-and-other-pillars-of-civilization/
bertrandmeyer.com/2010/02/06/reflexivity-and-other-pillars-of-civilization/
0
Я не гуру js, я его только изучаю, и могу посоветовать замемечательную книгу Дэвида Флэнагана «Javascript Подровное руководство». В ней отлично описан каждый из ваших случаев.
+6
NaN === NaN; // false
неизвестно что != неизвестно что
неизвестно что != неизвестно что
+23
Абсолютно согласен. Возможно просто костыль от разработчиков, по тому что логика в этом безусловно есть.
А вот
alert(111111111111111111111); // alerts 111111111111111110000
Наверняка связано с тем что скрипт считает 111111111111111111111 бинарным числом, пытается перевести в десятичную систему, но срабатывают ограничения integer. Может я и неправ, но это, на мой взгляд, наиболее вероятная причина такого поведения
А вот
alert(111111111111111111111); // alerts 111111111111111110000
Наверняка связано с тем что скрипт считает 111111111111111111111 бинарным числом, пытается перевести в десятичную систему, но срабатывают ограничения integer. Может я и неправ, но это, на мой взгляд, наиболее вероятная причина такого поведения
-4
UFO just landed and posted this here
Скорее не так. Любая операция, кроме IS NULL и IS NOT NULL, с NULL'ом даёт NULL. Таким образом NULL = NULL — это NULL, который затем интерпретируется как false, что и выглядит как будто NULL != NULL.
+1
UFO just landed and posted this here
о! раскрыли глаза на жизнь — благодарю! а пруф линк есть?
0
en.wikipedia.org/wiki/Null_(SQL)#Three-valued_logic_.283VL.29
Каюсь. Согласно этому всё немного не так. Но предложенная мной методика продолжает работать.
Каюсь. Согласно этому всё немного не так. Но предложенная мной методика продолжает работать.
0
Вышеуказанное число превышает допустимую безопасную длину, и поэтому теряется точность в младших разрядах. (Д. Фленаган, «JS. Подробное руководство», раздел 3.1.1)
+7
в С# приведение типов от большего к меньшему приводит к подобному результату, это нормально =)
0
Скрипту все равно, 11 или 11111111111111111. И 11 это одиннадцать, а не два. Было бы странно считать число двоичным лишь потому, что в нем нет цифр выше 1.
+1
О, моя бага там тоже есть? Круто. Только не мной подписано, но это сейчас поправим.
Дело, кстати, не в бинарности, а в том, что заканчивается точность floating point.
Дело, кстати, не в бинарности, а в том, что заканчивается точность floating point.
+1
Это похоже на операции сравнения с NULL в sql. Как известно, любая операция над NULL возвращает NULL и любая операция сравнения возвращает «неизвестно» или FALSE если операция сравнения с NULL это вся логическая операция.
То, что и с NaN это так же, абсолютно логично.
То, что и с NaN это так же, абсолютно логично.
+1
Тю, не заметил линк
+5
«Javascript — это язык, который мы любим несмотря на все его ненавистные особенности».
Взяв во внимание вышенаписанную фразу хочу поинтересоваться — кто-нибудь хоть раз сталкивался с проблемами при кодировании из-за вышеперечисленных странностей? Вряд ли. Те, кто находят эти странности подают их под таким соком, будто после таких багов язык для программирования не пригоден вовсе становится.
Взяв во внимание вышенаписанную фразу хочу поинтересоваться — кто-нибудь хоть раз сталкивался с проблемами при кодировании из-за вышеперечисленных странностей? Вряд ли. Те, кто находят эти странности подают их под таким соком, будто после таких багов язык для программирования не пригоден вовсе становится.
+4
Думаю, многие сталкивались с проблемами по крайней мере из-за следующих двух «странностей»:
parseInt('08'); // 0 0.1 + 0.2 === 0.3 // false
-4
в 8-ричной системе не может быть цифры 8.
+6
Где странности? С восьмеричной системой, как уже подметили, или с компьютерным преставлением чисел с плавающей точкой?
+4
видимо, автор сайта wtfjs пришёл в js не из программирования, а из верстки. Думаю, многие верстальщики именно из js узнали, что числа бывают восьмеричными и об особенностях компьютерного представления чисел с плавающей точкой.
Просто эти 2 примера, если о них не знать, способны порождать реальные проблемы при кодировании — в отличие от остальных, в большей степени относящихся именно к js.
Просто эти 2 примера, если о них не знать, способны порождать реальные проблемы при кодировании — в отличие от остальных, в большей степени относящихся именно к js.
+3
UFO just landed and posted this here
0.1 + 0.2 === 0.3 — проблема встречается не только в javascript, связана с представлением чисел с плавающей точкой
+3
второй правильнее так: 0.1 + 0.2 — 0.3 < 0.0001 где 0.0001 — точность сравнения
+1
(0.1 + 0.2).toPrecision(3) == (0.3).toPrecision(3)
+4
parseInt('08',10); //8
+7
смотрим еще:
[] == false // true
а теперь:
var a = [];
if (a) {
alert(1); // но мы тут, надо проверять свойство lenght
} else {
alert(2); // исходя из первого утверждения, можем решить, что окажемся здесь
}
[] == false // true
а теперь:
var a = [];
if (a) {
alert(1); // но мы тут, надо проверять свойство lenght
} else {
alert(2); // исходя из первого утверждения, можем решить, что окажемся здесь
}
-4
UFO just landed and posted this here
Я считаю себя гуру Javascript. И мне глубоко наплевать на эти «особенности», потому что ни один вменяемый программер такими конструкциями пользоваться не будет, и вовсе не потому, что JS выдает странный результат. А я очень надеюсь, что подобный код я никогда в жизни не увижу.
+9
Все примеры достаточно просты, по-моему. Не будучи гуру джаваскрипта, но в свое время с удовольствием прочитав Фланагана, ни разу не ошибся.
+3
Результаты приведенного кода верны (если знать Javascript), кроме typeof null == 'object' (это ошибка в первой реализации JS, которую скопировали реверс-инжереры из MS и потом пошла по всем браузерам).
+2
UFO just landed and posted this here
null вполне существующее значение, в отличии от undefined где значения по сути нет
0
> в отличии от undefined где значения по сути нет
Значение undefined есть ;) Свойство undefined глобального объекта имеет значение undefined.
Значение undefined есть ;) Свойство undefined глобального объекта имеет значение undefined.
+2
какой тогда в нем смысл? разве что для безопасного сравнения с несуществующими переменными, тогда эта запись глобального объекта для виду только… или в чем прикол?
-1
Значение undefined (по словам B.Eich) было введено для обособления инициализирующего значения переменных, либо, когда свойство не может быть найдено в базовом объекте.
Значение же null, в отличие от undefined, по смыслу больше связано с объектами, означает пустую ссылку на объект, возможно, зарезервированное место под объект.
Хотя, на мой взгляд, можно было выбрать что-то одно ;)
javascript.ru/blog/Dmitry-A.-Soshnikov/Tonkosti-ECMA-262-3.-CHast-7.-OOP.#tipy-dannyh
Значение же null, в отличие от undefined, по смыслу больше связано с объектами, означает пустую ссылку на объект, возможно, зарезервированное место под объект.
Хотя, на мой взгляд, можно было выбрать что-то одно ;)
Здесь есть одна особенность и связана она с оператором typeof, который часто может сбивать с толку, если не знать, как он работает. В большей мере это относится к значению null: несмотря на то, что тип null-a, по определению, Null, typeof для этого значения выдаёт «object»:
alert(typeof null); // «object»
А дело в том, что оператор typeof возвращает строковое значение, взятое из жёстко закреплённой таблицы, где прописано: «для null — возвращать „object“.
Причины этого в стандарте не разъясняются, однако B. Eich (создатель Javascript) отмечал, что null, в отличии от undefined (который означает неопределённость, „нет значения“), используется в большинстве случаев там, где фигурируют объекты, т.е. является некой сущностью, тесно связанной с объектами (конкретно, означающей нулевую ссылку на объект, „пустышку“, возможно, зарезервировавшую место для будущих целей). Но, в некоторых черновиках (например, в невышедшем ECMAscript4 aka Javascript 2.0), был заведён документ, где данный „феномен“ описан, как обычный баг. Также, данный баг поднимался в одном из баг-треккеров, в котором B. Eich также участвовал; в итоге было решено оставить typeof null, как есть, т.е. „object“, хотя сам стандарт ECMA-262-3 описывает тип null-a, как Null.
javascript.ru/blog/Dmitry-A.-Soshnikov/Tonkosti-ECMA-262-3.-CHast-7.-OOP.#tipy-dannyh
+4
Чтобы знать ответы на эти вопросы, совсем не обязательно быть гуру Javascript. Достаточно прочитать пару подобных статей, которые появляются довольно часто, в том числе и на Хабре, и содержат процентов на 80 одни и те же примеры.
+1
UFO just landed and posted this here
Про null как бы логично, оно не может быть ни false ни true. NaN тоже не может быть идентично другому NaN. Это же не переменная и не константа, это не существующее, не существующее нельзя с чем-то сравнивать.
-1
Не так давно мне вот такая особенность взломала мозг:
var wtf = somevar = {};
somevar.msg = 'hey, wtf';
alert(wtf.msg); //o_O wtf?
-9
wtf и somevar очевидно ссылки на один и тот же объект
+6
Понимаю, но неожиданно это.
-5
Что в этом неожиданного? Объекты в JS передаются по ссылке, это и новичку должно быть известно.
+7
> Объекты в JS передаются по ссылке
«По разделению» (либо по особому виду «по значению»): javascript.ru/blog/dmitry-a.-soshnikov/tonkosti-ecma-262-3.-chast-8.-strategiya-peredachi-parametrov-funkciu.
Переменные «разделяют» (share) один объект. Но если одной из этих переменных присвоить другое значение, это не значит, что все остальные переменные начнут ссылаться на этот новый объект, как было бы при передаче «по ссылке».
«По разделению» (либо по особому виду «по значению»): javascript.ru/blog/dmitry-a.-soshnikov/tonkosti-ecma-262-3.-chast-8.-strategiya-peredachi-parametrov-funkciu.
Переменные «разделяют» (share) один объект. Но если одной из этих переменных присвоить другое значение, это не значит, что все остальные переменные начнут ссылаться на этот новый объект, как было бы при передаче «по ссылке».
+6
Поразительно. Шестеро человек, которые вас плюсанули — так и не понимают, как работает JS. При это ещё и меня минусанули :D Деградация Хабра.
Ещё раз: объекты в JS не передаются по ссылке, а передаются по особому виду «по значению», либо, так же известному как, «по разделению».
Ещё раз: объекты в JS не передаются по ссылке, а передаются по особому виду «по значению», либо, так же известному как, «по разделению».
+5
На самом деле я знаю, как это работает, но не могу запомнить, как это называется, поэтому по привычке называю так :) Возможно, другие люди тоже понимают, что «по ссылке» применительно к JS означает «по разделению».
+1
а какая по сути раница? если это преподнести как: присваивание = изменения адреса ссылки, а изменение переменной = изменение объекта по ссылке, по сути получим тот же результат на практите, и более понятное обьяснение для людей не знакомых с JS (помоему такие штуки в других языках называются указатели?)
+1
> а какая по сути раница?
В реализации, в изменении значений. В грамотности. В незаблуждении.
Однако, стоит сказать, что в Ruby, например, называют это (при той же реализации) — по ссылке (вероятно, по той же причине ;)).
> присваивание = изменения адреса ссылки, а изменение переменной = изменение объекта по ссылке
Да, это и есть передача «по значение (адреса)» или «по разделению», но не «по ссылке».
> помоему такие штуки в других языках называются указатели?
Да (с определёнными уточнениями). Для С++ из boost-a больше по смыслу подойдёт shared_ptr.
В реализации, в изменении значений. В грамотности. В незаблуждении.
Однако, стоит сказать, что в Ruby, например, называют это (при той же реализации) — по ссылке (вероятно, по той же причине ;)).
> присваивание = изменения адреса ссылки, а изменение переменной = изменение объекта по ссылке
Да, это и есть передача «по значение (адреса)» или «по разделению», но не «по ссылке».
> помоему такие штуки в других языках называются указатели?
Да (с определёнными уточнениями). Для С++ из boost-a больше по смыслу подойдёт shared_ptr.
+2
В Java (не JS, просто хочу показать как в разных стандартах по-разному описывают) то же самое с объектами. В спецификации говорят, что значений-объектов нет, есть только значения-ссылки-на-объекты. И вот эти ссылки уже передаются по значению (как и всё в Java).
+2
UFO just landed and posted this here
в любом языке так, объекты всегда передавались по ссылке (пхп4 не в счет)
-1
UFO just landed and posted this here
если вы когда-нибудь заглядывали в сорцы jQuery, там можно было встретить такое:
и
jQuery.fn = jQuery.prototype = {...}
и
// Expose jQuery to the global object
window.jQuery = window.$ = jQuery;
0
Мда… Учиться не пробовали?
+3
UFO just landed and posted this here
typeof null; // object null === Object; // false /* null, хоть и имеет тип "object", не является Object'ом */
Тут мне не очень понятно, а что, собственно, ожидалось? Аналогично:
var x = {}; typeof x; // object x === Object; // false /* x, хоть и имеет тип "object", не является Object'ом */
Может, вместо
===
использовать instanceof
? Будет веселее (хотя тоже всё логично):var x = {}; null instanceof Object; // false x instanceof Object; // true
0
всё кроме Number.MIN_VALUE достаточно очевидно, хотя и про первое тоже можно догадаться, если вспомнить такие же «трюки» на C/C++
+2
нет никакого трюка — object — тип, а Object — переменная
0
Сверху уже местами ответили, но я подытожу:
Number.MIN_VALUE > 0; // true
/*
Дело в том, что MIN_VALUE это наименьшее число, БОЛЬШЕ НУЛЯ
JS Doc: Number.MIN_VALUE равняется самому маленькому возможному номеру, который может обрабатывать Javascript. Т.е. 5e-324 (кстати а как оно на 64-х битных машинах?).
*/
typeof null; // object
null === Object; // false
/*
null, хоть и имеет тип «object», не является Object'ом (КО добавляет: Object — это тип, а null — это уже сам объект, пустой. Разница между типом данных и пустой ячейкой типа данных очевидна. Мнимая неочевидность здесь возникает из-за неявного определения объекта. )
*/
NaN === NaN; // false
/*
Впечатляет, да? Я не могу найти этому объяснения. Автор же просто предполагает, что некоторые люди любят иногда понюхать клей...
КО напоминает про существование троичной логики, а так же что NaN — это аббревиатура Not a Number, т.е. не число. Кирпич и Скамейка — не число, но Кирпич не тождественен Скамейке.
*/
typeof NaN; // number
/*
Вот это сильно. Если вдруг кто не помнит, NaN — not a number. (Вот это бы примеру выше дописать!)
JS Doc: Number.NaN — этого достаточно. Но все же дополню, что NaN — это член типа Number.
*/
PS местами не очень грамотно, не не хотел лезть в омут ООП в JS
Number.MIN_VALUE > 0; // true
/*
JS Doc: Number.MIN_VALUE равняется самому маленькому возможному номеру, который может обрабатывать Javascript. Т.е. 5e-324 (кстати а как оно на 64-х битных машинах?).
*/
typeof null; // object
null === Object; // false
/*
null, хоть и имеет тип «object», не является Object'ом (КО добавляет: Object — это тип, а null — это уже сам объект, пустой. Разница между типом данных и пустой ячейкой типа данных очевидна. Мнимая неочевидность здесь возникает из-за неявного определения объекта. )
*/
NaN === NaN; // false
/*
КО напоминает про существование троичной логики, а так же что NaN — это аббревиатура Not a Number, т.е. не число. Кирпич и Скамейка — не число, но Кирпич не тождественен Скамейке.
*/
typeof NaN; // number
/*
Вот это сильно. Если вдруг кто не помнит, NaN — not a number. (Вот это бы примеру выше дописать!)
JS Doc: Number.NaN — этого достаточно. Но все же дополню, что NaN — это член типа Number.
*/
PS местами не очень грамотно, не не хотел лезть в омут ООП в JS
+9
parseInt('0105'); // 69
;)
;)
-1
О некоторых таких особенностях я писал в статье "Необычные особенности Javascript". Мне больше всего нравиться вот этот пример: a[[[[«item»]]]]==a[«item»]; // результат true
+2
Чикуёнок негодует =)
0
Sign up to leave a comment.
Ох уж этот javascript