О функциональном программировании в JavaScript
JavaScript функции
Замыкание — это внутренняя функция, у которой есть доступ к переменным, объявленным внутри родительской функции, даже после выполнения родительской функции.
Функция высшего порядка — это функция, которая способна принимать другие функции в качестве аргументов, возвращать функции, или делать и то и другое.
Функциональное программирование в JS освещается во множестве публикаций. Если вам это интересно — вот несколько материалов на данную тему, посвящённых
Учебник по синтаксису JavaScript
Перед тем как приступить к чтению учебника по языку JavaScript
, вы должны обладать знаниями по .
Будет большим плюсом в изучении синтаксиса JavaScript, если вы уже знакомы с каким-нибудь языком программирования, например PHP
, C
или Pascal
, а также понимаете что такое переменная, тип данных, функция или массив.
Однако если вы не знакомы с языками программирования, то волноваться не стоит, данный учебник по JavaScript
как раз и расчитан на тех, кто впервые приступает к изучению программирования.
JavaScript (ЯваСкрипт)
— это клиентский язык программирования, с помощью которого можно управлять элементами HTML-страницы (HTML-тегами) и веб-браузера, заставлять их двигаться, реагировать на различные события (щелчки мышью, нажатие на клавиатуру), создавать множество интересных программ (скриптов): тесты, анимацию, фотогалереи (например как во Вконтакте), игры и многое другое.
How to Complete the JavaScript Projects for Beginners Challenge
Completing the 100 JavaScript Project for Beginners Challenge is Simple (But not easy)
- Follow the link to one of the projects above.
- Read the description and follow the link on the project’s page to see how it functions (If the link is not available yet, it means I haven’t yet completed the project. But no worries. You can simply go to the course where I found the project).
- For the projects I’ve completed, download or clone my repository from GitHub.
- Delete the contents of the app.js file (or any other relevant js files) and then try to code out the JavaScript functionality for yourself.
- Once you complete the app, share it in the comments on the JavaScript project page on this blog so everyone can acknowledge your accomplishment! That’s it!
Система прототипов
Let service = {
doSomething: function() {}
}
let specializedService = Object.create(service);
console.log(specializedService.__proto__ === service); //true
Здесь, для создания объекта specializedService , прототипом которого нужно было сделать объект service , использована команда Object.create() . В результате оказывается, что метод doSomething() можно вызвать, обратившись к объекту specializedService . Кроме того, это означает, что свойство __proto__ объекта specializedService указывает на объект service .
Создадим теперь похожий объект с использованием ключевого слова class:
Class Service {
doSomething(){}
}
class SpecializedService extends Service {
}
let specializedService = new SpecializedService();
console.log(specializedService.__proto__ === SpecializedService.prototype);
Методы, объявленные в классе Service , будут добавлены в объект Service.prototype . Экземпляры класса Service будут иметь тот же прототип (Service.prototype). Все экземпляры будут делегировать вызовы методов к объекту Service.prototype . В результате оказывается, что методы объявляются лишь один раз, в Service.prototype , после чего «наследуются» всеми экземплярами класса.
How Long Should it take you to Complete these 100+ JavaScript Projects?
The time it takes to complete all the projects will vary based on your JavaScript skills and your schedule.
If you’re a true beginner, I recommend you start with The Modern JavaScript course before beginning here.
Andrew’s course alone is over 29 hours! Which means it’ll likely take you a total of 60 hours just to get through his course. But once you complete his course, you can return here.
Then, you’ll need about an hour to several hours per each JavaScript project above.
Some projects are simple JavaScript projects for beginners and will take about 10 minutes and others can take up to an entire weekend!
But don’t fear, even if it takes you six months to get through all of these projects, this is only a small period of your life relative to the time you’ll spend for the rest of your life as a full-time JavaScript developer.
Вместо заключения: убираем за собой
Я уже писал, что после завершения работы внешней функции и ее удаления из памяти внутренняя (вложенная) функция продолжает хранить ее переменные в своем скрытом свойстве .
В JS, как и во многих других языках, очисткой памяти занимается Сборщик мусора. Как и когда удаляются из памяти переменные внешней функции в нашей ситуации?
function f() { let value = 123; return function() { alert(value); } } let g = f(); // g.`Environment` хранит ссылку на объект лексического окружения функции f()
В приведенном выше примере в сохраняется переменная и остается там даже после того, как мы вызовем функцию и она завершит работу. Хотя известно, что переменные, объявленные как , должны уничтожаться при выходе из блока. Должны, да не обязаны.
Более сложный пример лучше показывает масштаб бедствия: все в три раза хуже. У нас теперь появляются целых три копии переменной . Каждый раз при вызове функции выделяется и не очищается память под новую копию лексического окружения (читай: новый объект ):
function f() { let value = Math.random(); return function() { alert(value); }; } /* Создадим массив из трех функций f(). В этом случае каждый экземпляр функции (напоминаю, в JS функция — это тоже объект) хранит свою копию объекта лексического окружения */ let arr = ;
Ну что же, тогда мы будем самостоятельно следить за распределением и очисткой памяти в подобных ситуациях. Когда нам становится не нужен объект и в частности все переменные внешнего лексического окружения, скажем об этом прямо:
В принципе, все. Только не забудьте сделать так, чтобы эта очистка памяти происходила в нужном месте и в нужное время.
История JavaScript
JavaScript был создан за 10 дней автором Бренданом Айком (Brandan Eich), работавшим на Netscape в далёком 1995 году. Изначально он был назван Mocha, имя языка было сменено на Mona и потом на LiveScript пока наконец он не стал JavaScript. Первоначальная версия языка была ограничена только браузером Netscape и предлагала узкую функциональность, но со временем он продолжил развиваться частично благодаря сообществу разработчиков, которые не оставляли работу над ним.
В 1996 году язык JavaScript был стандартизирован и было дано официальное имя ECMAScript, с ECMAScript 2 вышедшим в 1998 и ECMAScript 3 в следующем 1999 году. Это преобразовалось в сегодняшний JavaScript, которые теперь работает не только в разных браузерах, но также на различных устройствах, включая мобильные и настольные компьютеры.
JavaScript продолжил рост с тех пор до показателей 92% сайтов, использующих его в 2016 году. Всего за двадцать лет он превратился из примитивного языка программирования в один из наиболее популярных инструментов в арсенале веб-разработчика. Если вы используете интернет, то вы непременно сталкивались с JavaScript.
Эффективная проверка дат
Инструментарий JavaScript для работы с датами очень прост и не достаточен для форматирования дат. Хотя существует множество библиотек которые существенно облегчают обработку дат, часто нужно просто проверять дату в строке. Для такого случая отлично подходит следующий скрипт. Он позволяет проверить дату с любым разделителем и годом, указанным 4-мя цифрами.
function isValidDate(value, userFormat) { // Используем формат по умолчанию, если ничего не указано userFormat = userFormat || 'mm/dd/yyyy'; // Находим разделитель исключая символы месяца, дня и года (в английском варианте - m, d, y) var delimiter = //.exec(userFormat); // Создаем массив из месяца, дня и года, // то есть мы знаем порядок формата var theFormat = userFormat.split(delimiter); // Создаем массив из даты пользователя var theDate = value.split(delimiter); function isDate(date, format) { var m, d, y, i = 0, len = format.length, f; for (i; i < len; i++) { f = format; if (/m/.test(f)) m = date; if (/d/.test(f)) d = date; if (/y/.test(f)) y = date; } return ( m > 0 && m < 13 && y && y.length === 4 && d > 0 && // Проверяем правильность дня месяца d <= (new Date(y, m, 0)).getDate() ); } return isDate(theDate, theFormat); }
Следующая строка вернет false, так как в ноябре 30 дней:
isValidDate('dd-mm-yyyy', '31/11/2012')
Демонстрация использования кода
Scope и Scope Chain
Область действия состоит из переменных и функций, даже если они не были объявлены в самой функции. JavaScript имеет лексическую область видимости, что означает, что область определяется в зависимости от того, где функция объявлена в коде.
function a() { function b() { console.log(foo); // logs 'bar' } var foo = 'bar'; b(); } a();
При достижении console.log(foo), движок JavaScript сначала проверит, есть ли переменная foo в области контекста выполнения b(). Поскольку там ее нет, он перейдет в «родительский» контекст выполнения, который является контекстом выполнения a(), просто потому, что b() объявлен внутри a(). В области видимости этого контекста выполнения он найдет foo и выведет ее значение.
Если мы определим b() вне a(), вот так:
function a() { var foo = 'bar'; b(); } function b() { console.log(foo); // throws ReferenceError: foo is not defined } a();
Будет сгенерировано ReferenceError, хотя единственное различие между ними заключается в месте, где объявлено b().
«Родительская» область действия b() теперь является глобальной областью контекста выполнения, поскольку она объявляется на глобальном уровне вне какой-либо функции, и там нет переменной foo.
Я могу понять, почему это может сбивать с толку, потому что, если вы посмотрите на стек выполнения, это выглядит так:
JavaScript execution stack
Таким образом, легко предположить, что «родительский» контекст выполнения является следующим в стеке, ниже текущего. Однако это не так.
В первом примере контекст выполнения a() действительно является «родительским» контекстом выполнения b(). Не потому, что a() является следующим элементом в стеке выполнения, чуть ниже b(), а просто потому, что b() объявлен внутри a().
Во втором примере стек выполнения выглядит так же, но на этот раз «родительский» контекст выполнения b() является глобальным контекстом выполнения, потому что b() объявлен на глобальном уровне.
Просто помните: не важно, где вызывается функция, важно, где она объявлена. Но что произойдет, если она не сможет найти переменную в области «родительского» контекста выполнения?
Но что произойдет, если она не сможет найти переменную в области «родительского» контекста выполнения?
В этом случае он попытается найти его в области действия следующего «родительского» контекста выполнения, который определяется точно таким же образом.
Если его там тоже нет, он попробует следующий и т. д., пока в конце концов не достигнет глобальной области контекста выполнения. Если он не сможет найти его там, он выдаст ReferenceError.
Это называется цепочкой областей действия (scope chain), и это именно то, что происходит в следующем примере:
function a() { function b() { function c() { console.log(foo); } c(); } var foo = 'bar'; b(); } a();
Сначала он пытается найти foo в области контекста выполнения c(), затем b(), а затем, в конце концов, a(), где он его найдет.
Примечание: Помните, что движок переходит только от c() к b() и a(), потому что они объявлены внутри другого, а не потому, что их соответствующие контексты выполнения располагаются поверх другого в стеке выполнения.
Если они не будут объявлены внутри другого, тогда «родительский» контекст выполнения будет другим, как объяснено выше.
Однако, если бы внутри c() или b() была другая переменная foo, ее значение было бы выведено на консоль, потому что движок прекратит «поиск» «родительских» контекстов выполнения, как только найдет переменную.
То же самое относится и к функциям, а не только к переменным, и то же относится к глобальным переменным.
Примечание. Несмотря на то, что в приведенных выше примерах я использовал только синтаксис объявления функции, область действия и цепочка областей действия работают точно так же и для стрелочных функций, которые были представлены в ES2015 (также называемой ES6).
Эксперимент 6
Эксперимент 6 будет хорошей тренировкой работы с MVC. Понимание MVC является крайне важным при изучении основ JavaScript-фреймворков. В эксперименте 6 следуйте учебнику Scotch.io для создания клона Etsy с использованием Angular.
Build an Etsy Clone with Angular and Stamplay научит вас как создавать веб-приложения на Angular, интерфейсы с API и как структурировать большие проекты. После прохождения всех уроков у вас должны быть ответы на следующие вопросы:
- Что такое веб-приложение?
- Как MVC/MVVM взаимодействует с Angular?
- Что такое API и какие функции выполняет?
- Как организовать и структурировать большие объемы кода?
- В чем преимущества разделения вашего интерфейса на компоненты?
Если вы хотите проверить свои силы и построить больше приложений на основе Angular, то попробуйте Build a Real-Time Status Update App with AngularJS & Firebase.
Современная разметка
Тег имеет несколько атрибутов, которые редко используются, но всё ещё могут встретиться в старом коде:
- Атрибут :
-
Старый стандарт HTML, HTML4, требовал наличия этого атрибута в теге . Обычно он имел значение . На текущий момент этого больше не требуется. Более того, в современном стандарте HTML смысл этого атрибута полностью изменился. Теперь он может использоваться для JavaScript-модулей. Но это тема не для начального уровня, и о ней мы поговорим в другой части учебника.
- Атрибут :
-
Этот атрибут должен был задавать язык, на котором написан скрипт. Но так как JavaScript является языком по умолчанию, в этом атрибуте уже нет необходимости.
- Обёртывание скрипта в HTML-комментарии.
-
В очень древних книгах и руководствах вы сможете найти комментарии внутри тега , например, такие:
Этот комментарий скрывал код JavaScript в старых браузерах, которые не знали, как обрабатывать тег . Поскольку все браузеры, выпущенные за последние 15 лет, не содержат данной проблемы, такие комментарии уже не нужны. Если они есть, то это признак, что перед нами очень древний код.
Самые основы JavaScript
Напомним необходимый минимум, чтобы писать на JavaScript: переменные, типы данных, циклы и условия, функции.
Переменная — это небольшая часть оперативной памяти, которой можно дать своё имя, а потом что-то там хранить: числа, строки и всё остальное. Самый простой способ объявить переменную — написать:
var i; ← просто объявили переменную i;
или var i = 15; ← объявили переменную i и сразу положили туда число 15.
Чтобы компьютер знал, как работать с какой переменной, используют типы данных — они говорят компьютеру, что именно лежит в переменной, например:
var a = 1; ← целое число;
var b = 0.75; ← дробное число;
var c = ‘Привет!’; ← строка;
var d = ; ← массив;
var f = true; ← логическое значение.
JavaScript относится к языкам со слабой типизацией — это значит, что если мы сначала положим в переменную число, а потом строку, то скрипт легко даст нам это сделать.
Вместо var вы часто встретите в чужом коде слово . Это тоже объявление переменной, но локальной: как только выполнится текущий кусок кода (например, цикл или функция), эта переменная самоуничтожится. Обычно глобальные переменные для всей программы объявляют через , а внутренние и временные переменные — через .
Циклы. Если нам нужно, чтобы компьютер сделал что-то несколько раз подряд, используют циклы. Главное, за чем следят в цикле, — чтобы он точно когда-нибудь закончился. Если этого не предусмотреть, то цикл будет выполняться бесконечно и программа зависнет.
В JavaScript есть три вида циклов:
Цикл for. В общем виде он выглядит так:
Начало — это с какого значения переменной мы начинаем работать в цикле, условие — до каких пор цикл будет выполняться, а шаг — это на какое значение будет меняться переменная цикла. Например, вот как можно вывести числа от 0 до 10 в цикле for:
Цикл while. Он сначала проверяет условие, потом выполняет то, что внутри цикла, потом снова идёт проверять условие, и так до тех пор, пока условие не станет ложным:
Выведем те же числа от 0 до 10:
Цикл do..while. Работает так же, как предыдущий, только мы сначала хотя бы раз выполняем тело цикла, а потом идём проверять условие:
Функции. В скриптах часто используют функции — это мини-программы, которые сначала описываются, а потом вызываются одной строкой. В общем виде функции выглядят так:
Например, эта функция выводит в консоль текущее время и дату:
А чтобы выполнить всё это хозяйство, достаточно написать в консоли или вызвать в коде одну команду:
Обратите внимание, что в коде выше в конце функции стоит слово return. Оно значит, что когда функция исполнится, она отдаст какое-то значение тому, что её вызвало
Если лично вы вызвали функцию из консоли, то лично вам в консоль вернётся значение текущей даты. А если вы хотите, чтобы эта дата вылезла в виде всплывающего окошка, нужно будет вызвать эту функцию вот так:
Что переводится как «Исполни функцию printCurrentDate без дополнительных аргументов, а её результат передай команде alert».
Кстати, как только функция выполняет команду return, она отдаёт нужные данные и перестаёт выполняться.
Аргументы функции. У функции могут быть аргументы: это способ сообщить что-то в функцию. Например, у вас может быть функция для проверки логина и пароля. Чтобы проверить их, вам нужно передать в функцию логин и пароль. Вы указываете при объявлении функции, что вам нужно передать в неё эти два параметра, и называете их по именам. Дальше внутри функции вы можете использовать эти имена. А при вызове функции вам нужно вместо имён передать уже настоящие данные.
Вот мы определили функцию, в которую передаются два параметра, а потом они проверяются:
А теперь вызываем эту функцию, но уже с нужными данными:
Вместо конкретных строк admin и qwerty можно передать в функцию значения других переменных, а также целые объекты, массивы и что угодно ещё. Представьте, что это такое окошко, через которое вы передаёте что-то в функцию.
Для чего нужен JavaScript?
Изначально JavaScript создавался для браузеров. Он был призван сделать веб-страницы более отзывчивыми для пользователя, более функциональными для коммерческих компаний, и более важными для человечества в целом. JavaScript выполнялся только на стороне клиента (браузеров) и был узкоспециализированным, пока в 2009 году не вышел Node.js — серверная платформа для работы с JavaScript. Благодаря ему JavaScript можно запустить теперь хоть в кофеварке.
Иными словами, JavaScript не просто стал всесильным в теории, но и на практике ворвался в список серверных языков программирования, таких как PHP, Python, Ruby, Go, C#, Java, и по сей день только наращивает позиции. Его используют известные компании: NASA, Netflix, PayPal, Twitter, LinkedIn, Uber, eBay и многие другие.
Кроме веб-разработки, с помощью Node.js развивают сферу IoT (англ. Internet of Things — интернет вещей), создают умные дома и программируют микроконтроллеры.
А если взять фреймворк Electron, то можно создать десктопное приложение под Windows, macOS или Linux с помощью веб-технологий. Этот фреймворк довольно молодой, но с помощью него создали, например, Skype для Linux и мессенджер Slack.
А что насчёт мобильной разработки? И тут JavaScript на коне рынке — с помощью React Native обыкновенный фронтендер может создать полноценное Android-приложение.
Как видно, сфера применения JavaScript стала весьма широкой. Человечество активно стремится к концепции одного языка программирования для всего, и JavaScript в списке первых претендентов на эту роль.
Используй разнообразные ресурсы
Когда вы изучаете что-то сложное, как например программирование, полезно использовать как можно больше различных ресурсов с информацией. Перед вами несколько хороших способов дополнить свое обучение JavaScript с нуля:
- Онлайн-видео. Если вы ищете более подробное объяснение вашей проблемы, которую вы не можете понять, отправляйтесь на YouTube. Вы почти наверняка найдете видео, которое объясняет вещи в понятной форме, позволяя вам получить более глубокое понимание рассматриваемой концепции.
- Справочные руководства — Как отмечалось выше, справочные руководства необходимы, если речь идет об изучении и использовании любого языка программирования.
- Другие программисты — В интернете есть буквально сотни высококлассных форумов по программированию и чатов. Вы почти наверняка найдете кого-то, кто может помочь вам с любым возникшим вопросом.
- Онлайн-курсы — если вы еще не записались на бесплатные или недорогие онлайн-курсы по программированию, то теперь у вас есть шанс! Узнайте больше о курсах JavaScript на платформе BitDegree.
Может быть очень трудно начать изучать язык программирования, такой как JavaScript. Однако все будет намного проще, если вы будете использовать весь спектр доступных вам ресурсов.
Заключение
Изучение языка программирования, такого как JavaScript, может быть трудным. Поверь мне, я прошел через это и знаю, как трудно начать. К счастью для вас, теперь я знаю много вещей, которые я не знал, когда начал изучать свой первый язык программирования.
Я использовал эти знания, чтобы подготовить список советов для изучения того, как научиться писать код на JavaScript с нуля, который вы только что закончили читать. Если вы серьезно относитесь к тому, чтобы стать достойным программистом и устроиться на свою первую работу в backend разработке, то эти советы помогут вам быстро отследить ваш путь к освоению JavaScript.
Убедитесь, что вы регулярно практикуете программирование, делайте заметки, когда изучаете новые концепции, и используете весь спектр доступных вам ресурсов. Прежде всего, начни программировать!
Как добавить JavaScript на сайт?
Добавить строку кода JavaScript на сайт можно используя тэг <script>. Вы можете использовать следующий пример для наглядности того, как это выглядит на практике:
<script type="text/javascript"> Your JavaScript code </script>
Как основное правило, вставка вашего кода JavaScript внутри тэгов <header>, если только вам не нужно его выполнение в определённое время или на определённых элементах страницы. Вы также можете сохранить свой код JavaScript в отдельном файле и вызвать его там, где понадобится на сайте.
Для большей информации вы можете почитать наше другое руководство о том, как добавить JavaScript на свой сайт.
Итак, что такое JavaScript?
JavaScript — это язык программирования, который оживляет сайт. В отличие от HTML (который определяет контент) и CSS (который задаёт стили) и в отличие от PHP (который является языком стороны сервера), он запускается на стороне устройств посетителей.
Что нужно знать:
- JavaScript относительно прост в освоении;
- Он разработан Netscape, сейчас его используют более 92% сайтов;
- JS может быть привязан к конкретному элементу страницы или события вроде клика;
- Он работает на разных устройствах и в разных браузерах;
- Он быстрее и легче, чем другие языки программирования;
- Может быть менее безопасным, чем другие из-за своей популярности;
- Вы можете добавлять JavaScript непосредственно в HTML или вы можете хранить отдельные файлы и вызывать функциональность по необходимости.
И наконец, причина по которой JavaScript такой популярный: он очень хорош в том, для чего он предназначен. Если вас интересует JS для начинающих, надеемся эта статья вам помогла и теперь вы представляете, что такое JavaScript и как он работает.
Сравнение с другими ЯП
Мы разобрались с тем, что пишут на JavaScript, и отсюда можно сделать вывод, что JavaScript — монополист в своём сегменте. И в том, что касается фронтенд-разработки, — так оно и есть. JavaScript — это по-прежнему единственный язык программирования для выполнения в браузере. Только на JavaScript можно создать веб-приложения, такие как Google Docs, Figma и прочие онлайн-инструменты, где вся логика работает прямо в браузере.
Технически веб-сайт возможно сделать на любом языке программирования, хоть на Assembly. Но уровень квалификации для этого нужен несравненно больший, как и затраченное для этого количество времени.
Поэтому если и сравнивать JS с другими языками программирования, то только в контексте серверной разработки.
Серверных языков довольно много, поэтому мы возьмём только самые популярные в 2022 году: Python и С#.
JS vs Python
Мы уже рассказывали подробно про преимущества и недостатки Python. Но если кратко, то у Python и JavaScript много общего:
-
Оба — языки программирования общего назначения.
-
Это интерпретируемые языки программирования, для работы каждого из них на компьютере должен быть установлен интерпретатор — программа для выполнения кода; у JS им является браузер.
-
Как и JavaScript, Python имеет слабую динамическую типизацию.
-
Оба языка очень популярны ввиду простоты использования (синтаксис Python проще, чем у JavaScript).
-
И у первого, и у второго огромное комьюнити, создавшее большое количество библиотек для всего, что только можно представить и автоматизировать.
-
Оба высокоуровневые, скриптовые языки программирования.
-
И Python, и JavaScript нужна платформа для бэкенд-разработки, например Django.
Но есть и значимые отличия между этими языками программирования:
-
Python медленнее (хотя в версии 3.11 разработчики очень хорошо поработали над этим недостатком).
-
Основная ниша Python — Data Science и научно-технический прогресс: нейронные сети, машинное зрение, искусственный интеллект и прочая работа с данными.
-
Python пускают к железу значительно чаще. Это означает, что для программирования микроконтроллеров между JavaScript и Python выбирают последний, хоть это и не их стезя изначально.
-
Python чаще выбирают в тех задачах, где нужна автоматизация бизнес-процесса.
JS vs C#
Название языка C# читается как «си шарп». Это детище компании Microsoft, наследник Java, взявший от него 90% функциональности. Изначально создавался для разработки десктопных приложений и игр под Windows. Но в последнее время C# оброс таким количеством удобных инструментов, что всё больше завоёвывает любовь у профессиональных разработчиков.
В чём сходятся C# и JavaScript:
-
Для серверной разработки на C# нужна платформа ASP.NET, то есть тут вы тоже не можете просто взять и начать писать сервер.
-
Многие синтаксические конструкции очень похожи.
На этом их сходства заканчиваются.
Теперь об отличиях от JavaScript:
-
С# — строго типизируемый, это означает, что вам всегда нужно думать о типах данных, которые дозволено использовать памяти компьютера.
-
С# — компилируемый, его команды переводятся в двоичный код и отправляются прямиком в процессор, поэтому С#-код выполняется быстрее, чем на JavaScript.
-
У С# синтаксис более строгий и сложный, чем у JS, но более лёгкий, чем у Java или C++.
-
Если JavaScript — мультипарадигменный язык программирования, то C# заточен на использование в объектно-ориентированном стиле — вы обязательно должны знать ООП.
-
Даётся новичкам не так просто, как JavaScript.
Перечисленные тут отличия — фундаментальные, то есть далеко не все, но, пожалуй, самые главные.