Прочитав данный перевод первоапрельской статьи о JavaScript я был удивлен тому, к каким мелочам могут придираться люди. И проблема не в самой статье, не в мемах и шутках о данном языке, а в том, что кто-то неиронично утверждает что JavaScript — плохой язык программирования. Но что, если попытаться его понять?


Ответьте на вопрос, если вы разрабатываете на JS, то что именно? Может быть вы работаете на FrontEnd-е, может вы разрабатываете небольшое BackEnd приложение на nodejs, а может вы являетесь разработчиком в банке где все ПО написано на нем? Если третий случай это про вас, то скорее всего вы где-то ошиблись.


Проблема в том что ни один язык программирования не сможет стать панацеей от использования разных ЯП для достижения определенных целей. Но почему-то кто-то до сих пор считает что какой-то язык да заменит все существующие, станет универсальным и вообще спасет весь мир. Но обычно инструменты создаются под решение конкретных задач (хоть тут слово «конкретный» может включать довольно обширный спектр этих самых задач), и даже швейцарский нож не решит всех ваших проблем.


JavaScript хорошо справляется с задачами, для которых его чаще всего используют. А большинство лулзовых случаев, которые были рассмотрены в вышеуказанной статье являются сферическими конями в вакууме и в реальной разработке попросту не будут применены.


Первым делом хотелось бы привести в пример следующий отрывок с кодом:


const x={
  i: 1,
  toString: function(){
    return this.i++;
  }
}

if(x==1 && x==2 && x==3){
  document.write("This will be printed!")
}

Действительно, условие будет истинным. В таких случаях у меня возникает два вопроса — «Зачем?!» и «Как так получилось?». Дать ответ на первый вопрос я к сожалению не могу. Но вот попытаться ответить на второй вполне. Как известно JavaScript — язык с динамической типизацией. В нем есть два способа сравнения — строгое (===) и с преобразованием типов (==). Если бы в коде было использовано строгое сравнение, то никаких проблем бы не возникло. Но во втором случае интерпретатор пытается привести оба операнда к одному типу (строке) и сравнить их значения. Но почему-то истинность условия `x == 1 && x == 2 && x == 3` кому-то кажется смешной, несмотря на то, что нечто подобное можно реализовать и в других языках:


public class JavaScript {
	public static void main(String[] args) {
		AnonymousObject x = new AnonymousObject(1);

		if (x.equals(new AnonymousObject(1)) && x.equals(new AnonymousObject(2)) && x.equals(new AnonymousObject(3))) {
			System.out.println("JavaScript == Java // true");
		}
	}
}

class AnonymousObject {
	public int i;

	public AnonymousObject(int i) {
		this.i = i;
	}

	public boolean equals(AnonymousObject that) {
		return this.i++ == that.i;
	}
}

Кто-то скажет что тут использована функция .equals(), а там .toString(), что они предназначены для разных целей, что имплементация функции .toString() не должна влиять на сравнение, да и вообще это другое. Но если использовать строгие сравнения в JS то проблемы не будет, а вот в Java данное условие всегда будет истинно.


Ещё есть претензия к функции .sort(), мол она сортирует лексикографически:


[-2, -7, 0.0000001, 0.0000000006, 6, 10].sort()
// [-2, -7, 10, 1e-7, 6, 6e-10]

Но передадим мы функцию для сравнения и все внезапно работает как надо:


[-2, -7, 0.0000001, 0.0000000006, 6, 10].sort((a, b) => a - b)
// [-7, -2, 6e-10, 1e-7, 6, 10]

Кто-то снова возразит, сказав что в <название ЯП> все работает как надо и что вы, когда переходите с одного языка на другой хотите чтобы все было как раньше. Но знаете, я начал изучение программирования с Паскаля, там оператором сравнения был один знак равно. Представляете как мне не хотелось переходить на современные языки из-за того что в них два, а то и три знака?!


Под конец хотелось бы обсудить многопоточность в JS. Причина, по которой в JavaScript-е нет нормальной реализации многопоточности не в том, что язык какой-то не такой и он просто не способен на что-то такое, а в сфере его применения — web разработка. Ведь язык программирования это всего лишь спецификация, а её реализация лежит на компиляторе / трансляторе / интерпретаторе. В веб-разработке вам в принципе не должна понадобиться возможность исполнять ваш код в несколько потоков. Если вам часто приходится прибегать к ней, то скорее всего вы делаете что-то не так. Если вам нужна многопоточность на nodejs, то как и написано в исходной статье для этого есть разные библиотеки: comlink, указанная там или paralleljs, которая на мой взгляд удобнее в использовании. А если вас не устраивает дополнительная зависимость, то скорее всего вам нужен другой ЯП. Получить все и сразу попросту не выйдет.


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


Есть всего два типа языков программирования: те, на которые люди всё время ругаются, и те, которые никто не использует.


UPD:

Прочитав комментарии я решил уточнить две вещи:


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


2. Я ни в коем случае не утверждаю, что JS лучший язык, способный заменить все остальные и спасти мир. Я наоборот, пишу что везде его применять не стоит. Да и статья в принципе не столько о JS, сколько о том, что хейтить языки только потому что они не нравятся именно вам, только потому что там что-то работает не так как вы ожидали не надо. JS это всего лишь язык, который я привожу в пример так как прочел статью именно о нем. На его месте мог бы быть любой другой язык, потому что хейт может быть в сторону любого из них