Как стать автором
Обновить

Комментарии 37

Есть языки которые критикуют и есть языки на которых не пишут.
В любом языке своих странностей хватает.
А цель проделанной работы какая ? Никогда такие статьи не понимал.

Цель в том чтобы читатель, в будущем наткнувшись на какую-нить чертовщину, вспомнил про тот или иной подвох. Статья вроде не критикует, просто показывает подводные камни (которые везде есть).

Цель в том чтобы читатель, в будущем наткнувшись на какую-нить чертовщину, вспомнил про тот или иной подвох. 

Мне кажется это вряд ли.

1. Быстрее решая задачу и столкнувшись с каким то вариантом найти решение в интернете за 2-3 минуты. Поиск ответа в статье займет намного больше времени.

2. Большая часть примеров такие, с которыми я ни разу не сталкивался в реальной жизни, они слишком не реальные.

Актуальность вопроса:

Я даже посидел подумал, для чего такие статьи могут быть полезны и нашел один вариант очень хороший и главное очень полезный вариант. За что спасибо автору.


> Статья вроде не критикует, просто показывает подводные камни (которые везде есть).


КРИТИКУЕТ ЕЩЁ КАК !!! Мне два минуса в карму автор поставил. Видимо он решил не думать, а поставить минусы, посчитав что это не конструктивный вопрос.

 КАК
КАК

Автор не мог поставить два минуса. За одного человека можно голосовать только один раз.

Ещё одна особенность JavaScript? ;)

Если ты профессионально и глубоко занимаешься языком, ты быстро впитываешь то, что здесь изложено.

Лично я порой обхожу использование некоторых конструкций т.к. не могу быть уверен в их использовании. Эта статья помогает понять их и реально расширяет мой инструментальный набор.

Следующий современный аспект, это использование статей как промптов ИИ. Например, у меня уже есть промпты которые я переношу из проекта в проект и они помогают решать нетривиальные задачи и находить неочевидные проблемы. Статьи в этом плане прекрасны, т.к. имеют примеры и ИИ хорошо по ним делает выводы.

Докинул третий за карманытьё на ровном месте.

Шикарная статья! Js мой "второй" язык по работе - но вот подставу с for я никогда не замечал - в шоке от того, что оно так работает)

Я-то как раз много раз с этим сталкивался, но выяснял рабочий вариант методом проб и ошибок, после чего шел дальше. А тут вот оно что

Ну, большую часть времени эта "подстава" делает ровно то, что было задумано, и не создаёт баги, а исправляет их. Не удивительно что её никто не замечает.

Печально, что в самом популярном языке на планете, такие ужастное проблемы. Но всё же в разработке не часто приходится сталкиваться с такими проблемами. Ожидаю, когда уже будет типизация и когда устранят большенство проблем. А eval, это зло и никогда не рекомендуется использовать.

И какие проблемы устранятся с типизацией? Типизации в самом js не будет никогда. Это все только для ide.

V8 научился запускать typescript без компиляции в js. По сути это оно и есть: js со статической типизацией

Можно ссылочку?

Я полагаю нода у себя внутри также и будет транспилировать ts в js

Нет. Никакой транспиляции, и никаких проверок. Проверять придется отдельно. Только стирание информации о типах (Type stripping). Именно поэтому ts поддерживается не в полном объеме. Не поддерживается то, что требует изменения кода js - типа перечислений или декораторов.

https://nodejs.org/api/typescript.html#type-stripping

Сам js во время работы и компиляции (в байткод) никаких проверок этой типизации не делает и не будет делать. Только ide (типа VSCode) этим будет заниматься. А движок js (пока только в Node) просто удаляет информацию о типах (заменяет ее пробелами).

Запускать-то научился, но типизация всё ещё только для IDE и CI.

Суть в том, что ни одну из 6 описанных проблем статическая типизация TypeScript не решит.

Типизация ?

Самое печальное, что этот мем уже неоднократно становился реальностью.

В Java подобных костылей тоже вагон и тележка в придачу. За десятилетия развития накопились.

На удивление, интересная статья.

странности, которым не хватило место: - и +0, NaN не равен самому себе, == и !=. так работает абсолютно любой язык. в других статься ещё было, что typeof NaN это number. это не спецификация js, а физическое устройство процессора

В списке любых языков есть Си?

Статья интересная, со многими "граблями" уже встречался. Но по своему опыту могу сказать, вряд-ли кто-то будет держать это всё в голове постоянно. Механизм такой: наткнулся => узнал => исправил => забыл

"JavaScript отстой, потому что '0' == 0!" — буквально каждый когда-либо

Да, эта часть JavaScript действительно ужасна, но сегодня в любом проекте есть линтер, который тут же заворчит на вас за такой код.

Ура! Согласен! Наконец-то будет статья которая не будет обсасывать сравнение чисел и строк!

  1. eval хуже, чем вы думаете

А, нет, расходимся. Автор решил пробить дно и писать об eval в 2025 году

Скриптовый язык состоит из костылей, чего тут странного.

Вставка элемента в массив. Если индекс выходит за пределы массива, массив наполняется пустыми элементами:

const msgArray = [];
msgArray[0] = "Привет";
msgArray[99] = "мир";

if (msgArray.length === 100) {
  console.log("Длина равна 100.");
}

Нет, не наполняется. Обновляется только длина, а сам массив становится "дырявым":

let x = [1];
x[9] = 2;
console.log(x.length); // 10
console.log(x.hasOwnProperty(0)); // true
console.log(x.hasOwnProperty(1)); // false

Очень подлая история с точкой с запятой. Когда-то писал что-то вроде

functionCalled(someArgs)
[1, 2, 3].includes(1)

и никак не мог понять, что ж за ерунда происходит. Через несколько минут стенаний и слёз пришло осознание. Всегда ставил точку с запятой, пока вот в новую команду не перешел. А там все болт на это забили. Ситуация, конечно, редкая и даже забавная в каком-то смысле, но только потом, когда ты пережил дебаг и осознание :)

А можно еще вот так

for (var i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}

не сильно отличается от

for (let i = 0; i < 3; i++) {
  setTimeout(() => console.log(i), 1);
}

но результат абсолютно разный

В какой-то степени это логично и скорее нюанс блочной видимости let. Так-то блок для каждой итерации цикла "свой", и значение замыкается "своё". Для var эта область функциональная, и поэтому цикл входит в нее "полностью". Можно представить как

for (let _ = 0; _ < 3; _++) {
  const i = _;
  setTimeout(() => console.log(i), 1);
}

---------- 
let i;
for (let _ = 0; _ < 3; _++) {
  i = _;
  setTimeout(() => console.log(i), 1);
}


да уж, JS был хорош лет 20 назад, когда надо было прикрутить простенькую логику к сайту на PHP. но сейчас он уже полностью морально устарел. когда там к WASM прикрутят нормальную поддержку взаимодействия с браузером, чтобы можно было полностью отказаться от JS и использовать нормальные современные языки программирования?

Вся статья - следствие незнания концептов работы и устройства JS и виртуальной машины. И ее бы не было, если бы люди читали документацию ;) А то как в цитате: «в мире так много магии, если не учить физику в школе».

Тем не менее, большинство высокоуровневых языков (JS, Java, C# и др.) захватывают переменные по ссылке:

Это не так, в C# замыкание работает иначе и захватывает саму переменную.
https://csharpindepth.com/Articles/Closures где-то тут про это было написано.

Но в циклах это особенно нежелательно: там обычно нужно что-то сделать с итератором внутри колбэка:
// Код на C#:
// выводит "3 3 3" — вероятно, не то, что ождали

Вообще-то, это именно ожидаемый результат.
setTimeout() подразумевает выполнение фрагмента кода через определённый промежуток времени. Не выполнение сейчас и получение результата через определённую задержку, а именно начало выполнения по прошествии указанного периода времени.
В данном случае очевидно, что цикл завершится быстрее, чем отработает таймаут ожидания (за исключением разве что прохода i == 0 и то вряд ли).
Таким образом, к моменту первого выполнения WriteLine цикл уже закончит свою работу и в i совершенно ожидаемо будет 3.

При этом, если переписать код на лямбду с параметром, то всё будет работать как и всегда работает в C# - передачей по значению.
В данном случае, если я ещё не всё окончательно забыл, передать значение по ссылке вообще невозможно, т.к. язык явно запрещает это.

В качестве "решения" стандарт ECMAScript сделал так, чтобы переменные цикла в заголовке for имели особое поведение

Именно поэтому JS - это ужасный язык, особое поведение на особом поведении едет и особым поведением погоняет.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации