компиляция самых странных решений в js
Подробнее
£ typeof NaN <• "number" > 9999999999999999 <• 10000000000000000 > 0.5+0.1==0.6 <• true > 0.1+0.2==0.3 <• false £ Math.max() <* -Infinity > Math.min() <• Infinity > []+[] • i •• » []+{> <• "[object Object]" > {}+[] <• 0 > true+true+true===3 <• true > true-true <• 0 £ true==l <• true £ true===l <• false > (• + [] + [] + *П) -length <• 9 > 9+"l" <• "91" > 91-"1" <• 90 > [ ] ==0 true Спасибо за изобретение JavaScript
it-юмор,geek,Прикольные гаджеты. Научный, инженерный и айтишный юмор
Еще на тему
А динамическая это когда ты вначале обьявил int a = 0, а потом a = "test string" и всё ок, теперь а - строка.
Запрещено:
1 + 0.1 — складывать целое с дробным
1u32 + 1u16 и 1.0f32 + 1.0f64 — типы разной ширины
let z: *const u32 = &8u16 — присваивать указатели или ссылки разных типов (ссылка в указатель того же типа — разрешено, обратно — запрещено, т.к. ссылка, в отличие от указателя, не может быть нулевой)
Тем не менее, можно писать 1 as _ + 0.1 as _ — тогда компилятор преобразует типы в какой-то общий, но только при условии, что подходит только один тип, иначе ошибка автовыведения.
Забавно, но на JS тоже есть библиотеки, поддерживающие привязку объектов к моделям - там класс-модель дополняется декораторами.
let price = getFromServer();
...
price = '<strong>$ ' + price + '</strong>';
let data = getJSON();
...
data = getFromJSON(data, 'носки');
...
data = 'Состав изделия: ' + data.composition;
При нормальном подходе к разработке подобные случаи не должны проявляться: в других языках для больших чисел не используют int, не сравнивают напрямую между собой дробные числа, полученные математическими операциями, не используют функции без аргументов где эти аргументы явно подразумеваются. Зачем совершать математические действия над объектами? в случае неоднозначностей очень желательно приводить типы (что есть обязательным в других языках и непонятны подгорания по этому поводу в отношении JS)
Это конечно теоретический вариант, не предлагаю использовать серьезно на практике.
Пример JSON:
{
"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]
}
Это объект типа ключ-значение, в котором ключу "employees" соответствует значение типа массив из объектов, которые в свою очередь содержат пары ключ-значение с для ключей "firstName" и "lastName"
Знак == в операциях с плавающей запятой использовать нельзя в абсолютном большинстве языков, включая все языки низкого уровня.
"===" - это строгое сравнение с требованием совпадения типа, как раз для тех, у кого подгорало от конвертации чисел в строки и наоборот.
Конкретно приведенный тут случая даже описан на W3Schools:
When using the === operator, equal booleans are not equal, because the === operator expects equality in both type and value.
boolean представлен просто как числа 1 и 0, как и ээ... да в абсолютном большинстве языков и даже СУБД.
Любая операция со знаком +, проведенная не над числом, вызывает метод toString(), у массива метод .toString() выводит все его элементы через запятую. Два пустых массива, соответственно, дают две пустые строки, которые при сложении дают тоже пустую строку.
Для объекта метод toString возвращает "[object ClassName]" - в примере выше просто "[object Object]"
Любая операция со знаком - подразумевает конвертацию в число.
И всегда, когда идет конвертация, подразумевается, что программист понимает, что он делает и зачем. Если зачем-то ему понадобилось сложить три булевы переменные, то вероятно он ожидает числовой ответ, не?
только у других ву-языков обычно для этого есть встроенные классы и методы
>Любая операция со знаком +, проведенная не над числом, вызывает метод toString()
а в более правильных языках вываливается types mismatch
>И всегда, когда идет конвертация, подразумевается, что программист понимает, что он делает и зачем.
или же он ожидал, что придёт массив, но кое-что наебнулось и пришёл null или буль
> а в более правильных языках вываливается types mismatch
К строкам во многих современных языках разрешено прибавлять числа.
А динамическая типизация внутри числовых типов (int, float, double) существует с доисторических времен.
> или же он ожидал, что придёт массив
От операции сложения массива с объектом посредством знака "+"? Я с трудом себе представляю подобное.
За годы практики понял три вещи:
# хер пойми какие кейсы (например сложить бесконечность с ложью и поделить на пустоту для получения неопределености) не проблема, ибо на практике такое писать не будешь.
# динамические скрипты сами по себе то еще приключение и без таких подводных камней впервую очередь из-за отсутствия ошибок "на этапе компиляции", а в рантайме валится чаще где-то дальше проблемного места.
# два преведущих пункта не повод переставать стебятся с того факта, какую лютую дичь можно наваять на JS.
Везде, где есть динамическая типизация, нужно указывать функцию сортировки.
Ошибки, незаметные на этапе компиляции, хорошо помогает исправить TypeScript.
https://www.destroyallsoftware.com/talks/wat
Брендон возглавляет комитет по разработке WASM, и судя по динамике разработки - очень хочет искупить свои грехи
Но во имя каких богов, Mathf.max() возвращает "минус бесконечность"
max = (...args) => {
let result = -Infinity
args.forEach(arg => {
if (arg > result) {
result = arg
}
})
return result
}
и минус бесконечность поставили, что бы первая проверка всегда была максимальным числом
при вычислении дробных значений в большинстве языков получаются приблизительные, а не математически точные значения. для точных значений используются специальные математические библиотеки или с числами работают как со строками, что во много раз медленней, занимает гораздо больше ОЗУ.