События, в результате которых появился JavaScript, разворачивались в течение шести месяцев, с мая по декабрь 1995 года. Компания Netscape Communications уверенно прокладывала себе путь в области веб-технологий. У них было всё необходимое для поиска способов дальнейшего развития веб-технологий.
Веб нуждался в лёгком скриптовом языке.
И тут в нашей истории появляется Брендан Айк, отец JavaScript. Айк должен был разработать для Netscape «Scheme для браузера». Scheme — это динамичный, мощный и функциональный диалект языка программирования Lisp с максимально упрощённым синтаксисом.
Перед командой была поставлена задача подготовить работающий прототип в кратчайшие сроки.
Mocha должен был стать скриптовым компаньоном для Java по принципу, аналогичному тому, как взаимодействуют C/C++ и Visual Basic на платформе Windows.
В течение нескольких недель был подготовлен рабочий прототип, который затем был интегрирован в Netscape Communicator.
То, что должно было стать аналогом Scheme для браузера, вылилось в нечто совершенно иное. Рукой Айка управляли необходимость закрыть сделку с Sun и сделать Mocha скриптовым компаньоном для Java. Синтаксис должен был быть максимально близким Java. Помимо этого, от Java была унаследована семантика для большого количества устоявшихся идиом. Таким образом, Mocha был совсем не похож на Scheme. Он выглядел, как динамический Java, под оболочкой которого скрывался гибрид Scheme и Self.
На выходе мы получили простой в освоении, динамичный, немногословный и мощный язык с множеством достоинств, такие как объектная модель и некоторые функциональные особенности.
Подобное может быть верным лишь для только родившегося JS.
Тогда его использовали примерно так.
Пожалуй, одной из самых больших ошибок, допущенных из-за спешки, в которой разрабатывался JavaScript, стало то, что объекты, ведущие себя совершенно идентично, могут быть различных типов. Например, тип строки (Hello world) не совпадает с типом нового объекта String (new String('Hello world')). Это порой приводит к нежелательным последствиям, которые могут сбить с толку.
object "hello world" и string "hello world"
Давайте рассмотрим еще один пример.
typeof null === object ???
В консоль будет выведено значение true. Такой результат будет из-за того, что JavaScript имеет старый баг. typeof null возвращает "object".
Эти баги существуют уже много лет и вероятнее всего уже никогда не будут исправлены. Это связано с тем, что написано слишком много кода, который полагается на подобное ошибочное поведение.
К слову, о стандартах. Стандартом языка является ECMAScript, его часто называют ES. Версия 1 была выпущена в июне 1997 года. Это событие открыло JavaScript для большей аудитории и дала возможность сторонним разработчикам принимать участие в развитии языка.
Но нужно помнить, что динамическая типизация несёт как большую власть, так и большую ответственность
Пример динамической типизации
Еще считается, что «нативное» предназначение JS — манипуляции с DOM. На самом деле это уже давно не так и JS успешно используется на сервере, в мобильных устройствах и даже в микроконтроллерах. Но речь не об этом. Речь о том, что когда вы с помощью JavaScript работаете с DOM, то тормозит не JS, а DOM. Есть много причин, почему DOM такой медленный, но я позволю себе сузить фокус только на одной причине. Проблема в самой спецификации HTML.
В разделе 1.1.1 The DOM Structure Model есть следующий абзац:
Есть такой проект под названием Benchmarks Game. Ребята написали программы (обход бинарных деревьев, n-body и т.д.) на всех популярных языках программирования и разработали методику измерения скорости и потребления памяти.
Из всех интерпретируемых языков JavaScipt работает быстрее других. На 2016-й год, он в пять раз быстрее, чем Python и Ruby (в том числе JRuby).
Когда дело доходит до наследования, в JavaScript есть только одна конструкция: объекты. Каждый объект имеет внутреннюю ссылку на другой объект, называемый его прототипом. У этого объекта-прототипа есть собственный прототип, и так до тех пор, пока не будет достигнут объект с нулевым значением в качестве его прототипа. null по определению не имеет прототипа и действует как последнее звено в этой цепочке прототипов.
Подобная архитектура вызывает следующие проблемы:
Знакомо?
Веб нуждался в лёгком скриптовом языке.
И тут в нашей истории появляется Брендан Айк, отец JavaScript. Айк должен был разработать для Netscape «Scheme для браузера». Scheme — это динамичный, мощный и функциональный диалект языка программирования Lisp с максимально упрощённым синтаксисом.
Перед командой была поставлена задача подготовить работающий прототип в кратчайшие сроки.
Mocha должен был стать скриптовым компаньоном для Java по принципу, аналогичному тому, как взаимодействуют C/C++ и Visual Basic на платформе Windows.
В течение нескольких недель был подготовлен рабочий прототип, который затем был интегрирован в Netscape Communicator.
То, что должно было стать аналогом Scheme для браузера, вылилось в нечто совершенно иное. Рукой Айка управляли необходимость закрыть сделку с Sun и сделать Mocha скриптовым компаньоном для Java. Синтаксис должен был быть максимально близким Java. Помимо этого, от Java была унаследована семантика для большого количества устоявшихся идиом. Таким образом, Mocha был совсем не похож на Scheme. Он выглядел, как динамический Java, под оболочкой которого скрывался гибрид Scheme и Self.
На выходе мы получили простой в освоении, динамичный, немногословный и мощный язык с множеством достоинств, такие как объектная модель и некоторые функциональные особенности.
Синтаксис и семантика языка
Самыми большими проблемами в JS считаются синтаксис и семантика языка. Вместе они создают уродливый и многословный язык, который обычно больно читать, как считают оппозиционеры.Подобное может быть верным лишь для только родившегося JS.
Тогда его использовали примерно так.
Исторические проблемы
Проблемы в языке, оставшиеся по историческим причинам, требуют костылей, но и они неповоротливы и сложны. Подобное возникло вследствие спешки еще при рождении языка, а если точнее, из-за обстоятельств, при которых была необходима эта спешка. Несмотря на это, часть проблем в языке была исправлена вместе со стандартизацией языка.Пожалуй, одной из самых больших ошибок, допущенных из-за спешки, в которой разрабатывался JavaScript, стало то, что объекты, ведущие себя совершенно идентично, могут быть различных типов. Например, тип строки (Hello world) не совпадает с типом нового объекта String (new String('Hello world')). Это порой приводит к нежелательным последствиям, которые могут сбить с толку.
object "hello world" и string "hello world"
Давайте рассмотрим еще один пример.
typeof null === object ???
В консоль будет выведено значение true. Такой результат будет из-за того, что JavaScript имеет старый баг. typeof null возвращает "object".
Эти баги существуют уже много лет и вероятнее всего уже никогда не будут исправлены. Это связано с тем, что написано слишком много кода, который полагается на подобное ошибочное поведение.
К слову, о стандартах. Стандартом языка является ECMAScript, его часто называют ES. Версия 1 была выпущена в июне 1997 года. Это событие открыло JavaScript для большей аудитории и дала возможность сторонним разработчикам принимать участие в развитии языка.
Динамическая типизация
Один из любимых доводов против JavaScript - динамическая типизация. Разработчики на статически типизированных языках считают дикостью подобное, поэтому и называют его недоязыком. Для таких случаев был разработан TypeScript, решающий эту проблему, что по большей части вопрос привычки каждого, сколько недостаток языка.Но нужно помнить, что динамическая типизация несёт как большую власть, так и большую ответственность
Пример динамической типизации
Скорость
Еще один любимый критерий оценки языков программирования - их скорость. Сложилось мнение, что JS - медленный.Еще считается, что «нативное» предназначение JS — манипуляции с DOM. На самом деле это уже давно не так и JS успешно используется на сервере, в мобильных устройствах и даже в микроконтроллерах. Но речь не об этом. Речь о том, что когда вы с помощью JavaScript работаете с DOM, то тормозит не JS, а DOM. Есть много причин, почему DOM такой медленный, но я позволю себе сузить фокус только на одной причине. Проблема в самой спецификации HTML.
В разделе 1.1.1 The DOM Structure Model есть следующий абзац:
Смысл в том, что объекты в дереве DOM — «живые». Это означает, что при любом изменении любой части DOM эти изменения отражаются в каждом объекте DOM.…objects in the DOM are live; that is, changes to the underlying document structure are reflected in all relevant NodeList and NamedNodeMap objects…
Есть такой проект под названием Benchmarks Game. Ребята написали программы (обход бинарных деревьев, n-body и т.д.) на всех популярных языках программирования и разработали методику измерения скорости и потребления памяти.
Из всех интерпретируемых языков JavaScipt работает быстрее других. На 2016-й год, он в пять раз быстрее, чем Python и Ruby (в том числе JRuby).
Безальтернативность
Также весомая причина нелюбви - безальтернативность. Формально, это не совсем так, но работая с вебом, ты будешь работать с JavaScript.Прототипная модель наследования
Путаницу, и вследствие, недовольство, вызывает прототипная модель наследования.Когда дело доходит до наследования, в JavaScript есть только одна конструкция: объекты. Каждый объект имеет внутреннюю ссылку на другой объект, называемый его прототипом. У этого объекта-прототипа есть собственный прототип, и так до тех пор, пока не будет достигнут объект с нулевым значением в качестве его прототипа. null по определению не имеет прототипа и действует как последнее звено в этой цепочке прототипов.
Подобная архитектура вызывает следующие проблемы:
- Изменение свойств прототипа может привести к неожиданным результатам: если свойство прототипа изменяется, это может повлиять на все объекты, наследующие этот прототип. Это может привести к неожиданному поведению приложения и усложнить отладку.
- Неправильное наследование свойств и методов: если объект наследует свойство или метод, который уже есть в его прототипе, это может привести к конфликту и непредсказуемому поведению приложения.
- Отсутствие явного связывания между объектами: прототипное наследование может быть неявным, что затрудняет понимание отношений между объектами и усложняет их дальнейшую модификацию.
Низкий порог входа
Якобы низкий порог входа в язык порождает собой еще больше сплетней исходит из стихии языка - JavaScript при его создании проектировался как простой скриптовый язык для динамичности страниц. Сейчас же в язык добавлено много возможностей для большого программирования и не делает его таким легким.Конец
Закончить хотелось бы цитатой:«Есть всего два типа языков программирования: те, на которые люди всё время ругаются, и те, которые никто не использует.» Bjarne Stroustrup
Знакомо?
Почему не любят JavaScript?
16 декабря 2023 в Краснодаре прошел бар-митап, на котором я в первые выступил с докладом с названием, указанным в заголовке статьи. Здесь будет его пересказ (записи докладов не производилось), а в...
habr.com