Использование javascript – Где посмотреть реальные примеры использования «правильных» клиентских javascript?

Для чего нужен и что делает Javascript. Примеры.

Если вы еще не знакомы с понятием Javascript, то об этом я писал тут.

В этой заметке хотелось рассказать о том, для чего Javascript нужен и что с его помощью можно делать.

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

Это могут быть условия «если-то», циклы, которые создают определенную последовательность действий, математические вычисления и.т.д.

Самое главное в том, что все эти операции можно производить на веб-страницах, в окне браузера. Причем, javascript может работать и без подключения к сети Интернет.

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

Все мои уроки по Javascript здесь.

1) Математические операции

На веб-страницах очень часто возникает необходимость произвести те или иные вычисления.

Например, есть два текстовых поля и нужно в третьем текстовом поле вывести сумму двух чисел, которые введены в первые два.

С помощью Javascript можно создать калькулятор и разместить его на веб-странице.

Вот здесь есть пример такого калькулятора:

http://www.javascriptkit.com/script/cut18.shtml

Еще ситуация, возьмем какую-нибудь текстовую строку на веб-странице, нужно увеличить ее размер в 1,5 раза. Это тоже можно сделать с помощью математических вычислений, путем умножения текущего размера на коэффициент 1,5.

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

2) Обработка и валидация данных в HTML-формах

Javascript позволяет проверять, что все требуемые поля заполнены и данные, которые в них находятся соответствуют нужному формату (например, если требуются цифры, то должны быть только цифры и не должно быть букв).

Делает это Javascript без перезагрузки страницы и даже без подключения к Интернет.

Прежде чем отправлять данные на сервер, они проходят предварительную проверку на Javascript. Это снижает нагрузку на сервер.

3) Взаимодействия с пользователем и события

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

Выпадающее меню на сайте при наведении курсора мыши.

При клике на кнопку скрыть или показать какой-то элемент на странице.

Появления всплывающего окна, когда курсор мыши ушел за пределы окна браузера.

Затемнение заднего фона и эффекты плавного появления элемента реализуются на Javascript.

И.т.д.

4) Взаимодействовать с HTML-элементами на странице и управлять их содержимым и стилями.

При наступлении определенного события (например, клик мыши или любого другого) можно изменять внешний вид (стили CSS) элементов на странице.

Делается это все программно.

Еще можно добавлять какие-нибудь HTML-теги или атрибуты к ним, также при наступлении определенного события.

5) Добавление анимации и различных графических эффектов на веб-страницы.

Падающие и двигающиеся объекты. Например, снег на сайт.

Плавное появление и скрытие объектов

Таймер обратного отсчета

И др. эффекты реализуются на Javascript

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

список сайтов, на которых опубликованы действующие примеры на языке javascript:

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

Все мои уроки по Javascript здесь.

особенности и сфера применения WebAssembly / RUVDS.com corporate blog / Habr

Сегодня мы представляем вам шестую часть серии материалов, которые посвящены особенностям работы всего того, что связано с JavaScript. Здесь мы поговорим о WebAssembly. А именно, детально проанализируем эту технологию, рассмотрим особенности её работы, а так же то, как она соотносится с обычным JavaScript в плане производительности. Речь пойдёт о времени загрузки кода, о скорости выполнения программ, о сборке мусора, об использовании памяти, о доступе к API платформы, об отладке, о многопоточности и о переносимости WebAssembly-кода. Эта технология, хотя и находится сейчас в самом начале своего развития, уже начала менять взгляды на разработку веб-приложений. Если разработчику нужна высочайшая производительность браузерного кода, ему просто необходимо познакомиться с WebAssembly.


[Советуем почитать] Другие 19 частей цикла

Что такое WebAssembly


WebAssembly (сокращённо — wasm) — это эффективный низкоуровневый байт-код для веб-приложений. Wasm даёт возможность разработки функционала веб-страниц на языках, отличных от JavaScript (например, это C, C++, Rust и другие). Код на этих языках компилируется (статически) в WebAssembly. В результате получается веб-приложение, которое быстро загружается и отличается очень высокой производительностью.

Время загрузки


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

Wasm — это низкоуровневый язык, похожий на ассемблер. WebAssembly-программы загружаются браузером быстрее, так как через интернет нужно передать уже скомпилированные файлы в весьма компактном бинарном формате.

Выполнение


Сегодня wasm-программы выполняются лишь на 20% медленнее чем машинный код. Это, без сомнения, достойный результат. Ведь речь идёт о формате, который компилируется в особом окружении и запускается с применением множества ограничений, которые обеспечивают высокий уровень безопасности. Подобное замедление в сравнении с машинным кодом в этом свете выглядит не таким уж и большим. Кроме того, в будущем ожидается повышение производительности wasm-кода. Ещё интереснее то, что wasm платформенно-независим. Его поддержка имеется во всех ведущих браузерных движках, которые демонстрируют примерно одинаковую производительность при выполнении wasm-кода.

Для того, чтобы сопоставить особенности wasm и JavaScript, вы можете обратиться к этому материалу, в котором идёт речь об особенностях JS-движков на примере V8. А сейчас мы поговорим о том, как wasm-код соотносится с другими механизмами V8.

Wasm и JS-движок V8


Вот схема устройства движка V8, а именно, тот путь, который проходит программа на JavaScript от простого текстового файла до исполняемого кода.
Динамическая компиляция в V8

Слева представлен исходный код на JavaScript, который содержит некую функцию. Сначала этот код подвергается парсингу, строки превращаются в токены и генерируется абстрактное синтаксическое дерево (Abstract Syntax Tree, AST). AST — это представление логики JS-программы. После создания AST V8 преобразует то, что получилось, в машинный код. Производится обход абстрактного синтаксического дерева и то, что раньше было функцией, существующей в виде текста, преобразуется в её скомпилированный вариант. При этом V8 не прилагает особых усилий для того, чтобы оптимизировать код.

Посмотрим теперь на то, что происходит на следующих стадиях работы движка.


Конвейер движка V8

Здесь показано, что теперь приходит время TurboFan — одного из оптимизирующих компиляторов V8. Во время работы JavaScript-приложения в V8 производится множество вспомогательных действий. А именно, TurboFan наблюдает за происходящим в поисках узких мест и наиболее часто используемых фрагментов программы для того, чтобы оптимизировать соответствующие участки кода. После этого TurboFan обработает наиболее ответственные части программы, пропустив их через оптимизирующий JIT-компилятор, что приведёт к тому, что те функции, которые «съедают» большую часть времени процессора, станут выполняться гораздо быстрее.

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

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


Wasm и конвейер V8

Wasm-код оптимизируется в ходе статической компиляции. При работе с ним не нужно разбирать текстовые файлы. Благодаря wasm в нашем распоряжении оказываются бинарные файлы, которые достаточно лишь преобразовать в машинный код. Все улучшения в этот код были внесены при компиляции, которая производится до того, как он попадает в браузер.
Всё это делает выполнение wasm гораздо более эффективным, так как немало шагов по превращению текста программы в оптимизированный машинный код можно пропустить.

Модель памяти



Доверенная и недоверенная области памяти WebAssembly

Память программы, написанной, например, на C++ и скомпилированной в WebAssembly, представляет собой непрерывный блок, в котором нет «дыр». Одна из особенностей wasm, которая способствует повышению безопасности, заключается в отделении стека выполнения от линейного адресного пространства. В C++-программах есть куча, память под стек выделяется в её верхней части. При подобной организации работы с памятью можно, воспользовавшись указателем, получить доступ к памяти стека для того, чтобы воздействовать на состояние переменных, взаимодействие с которыми на текущем этапе выполнения программы не предусмотрено. Именно эту возможность используют многие вредоносные программы.

WebAssembly пользуется совершенно другой моделью работы с памятью. Стек выполнения отделён от памяти, где хранится сама wasm-программа, в результате нет возможности получить несанкционированный доступ к этой памяти, и, например, изменить состояние каких-то переменных. Кроме того, функции используют не указатели, а целочисленные смещения. Здесь применяется механизм косвенной адресации. Необходимые прямые адреса вычисляются в процессе работы программы. Этот механизм построен так, что можно одновременно загрузить несколько wasm-модулей, адреса будут находиться с использованием смещений, в итоге всё будет работать как надо.

Подробнее о механизмах управления памятью в JavaScript можно почитать здесь.

Сборка мусора


В предыдущих материалах этой серии мы уже говорили о том, что в управлении памятью JS-программ участвует сборщик мусора (Garbage Collector, GC).

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

Сейчас WebAssembly ориентирован на способы работы с памятью, применяемые в C++ и Rust. Так как wasm — низкоуровневая технология, вполне логично то, что языки программирования, находящиеся лишь на одну ступень выше ассемблера, будут легко компилироваться в wasm. Так, при программировании на C можно использовать обычную команду malloc, в C++ можно применять интеллектуальные указатели. Rust задействует совершенно другой подход (не будем в это углубляться, так как там всё совершенно иначе). Эти языки не применяют сборщики мусора, в результате им не нужны сложные механизмы времени выполнения, которые отвечают за управление памятью. WebAssembly отлично вписывается в подобные модели работы с памятью.

Кроме того, эти языки не созданы для выполнения сложных операций, которые обычно реализуются с помощью JavaScript, таких, как манипуляции с DOM. Нет смысла писать HTML-приложение целиком на C++, так как C++ просто не рассчитан на такое применение. В большинстве случаев код для веб-приложений на C++ или Rust пишут для работы с WebGL или создают на нём высокооптимизированные библиотеки, например, такие, которые отвечают за математические вычисления.

В будущем, однако, ожидается поддержка языков, которые используют другие модели работы с памятью.

Доступ к внешним API


В зависимости от среды выполнения, JavaScript программа может напрямую взаимодействовать со специализированными API. Например, если программа написана для браузера, в её распоряжении оказывается набор Web API, которые приложение использует для управления браузером или устройством, и для работы с DOM, CSSOM, WebGL, IndexedDB, Web Audio API и так далее.

У модулей WebAssembly нет прямого доступа к API, который предоставляет платформа. Модули могут взаимодействовать с API только при посредничестве JavaScript. Если, из wasm-модуля, нужно обратиться к подобному API, этот вызов нужно выполнять через JavaScript. Например, если нужно выполнить команду

console.log, вызывать её придётся через JS. Подобные обращения к средствам JavaScript сказываются на производительности.

Нельзя говорить, что так будет всегда. В будущем ожидается появление соответствующих API для непосредственного использования их в wasm-коде. Как результат, wasm-приложения можно будет создавать, не используя обращения к JavaScript.

Карты кода (source maps)


Если после минификации JS-кода его нужно отлаживать, в дело вступают карты кода (source maps). Это — способ установления соответствий между JS-кодом, который минифицирован или скомбинирован из различных файлов, и его исходным состоянием. Когда проект собирают для продакшна, производят минификацию и комбинирование файлов, создают и карту кода, которая хранит информацию об исходных файлах. При обращении к конкретному месту в сгенерированном коде можно, сверившись с картой кода, найти фрагмент исходной программы, который выглядит гораздо понятнее, нежели упакованный вариант программы.

WebAssembly не поддерживает карты кода (source maps), так как пока нет соответствующей спецификации, но, вполне возможно, что уже весьма скоро такая возможность появится.

В результате, при отладке wasm-кода, полученного, например, из C++, можно будет видеть исходный код, устанавливать в нём точки останова. По крайней мере, такова цель внедрения карт кода в wasm.

Многопоточность


JavaScript выполняется в одном потоке, хотя он поддерживает асинхронную модель программирования. Подробнее об этом можно почитать здесь. Кроме того, JS поддерживает технологию Web Workers, но у неё довольно специфическая область применения.

Преимущественно —  вычисления, интенсивно использующие ресурсы процессора, которые могут заблокировать главный поток пользовательского интерфейса. Однако, код Web Workers не может работать с DOM.

В настоящий момент WebAssembly не поддерживает многопоточность. Однако, вероятнее всего, эта возможность появится совсем скоро. Wasm будет близок к низкоуровневым потокам (то есть — тем, которые используются в C++). Возможность работать с «настоящими» потоками создаст множество новых возможностей в разработке браузерных приложений. Но, конечно, многопоточность означает и появление новых сложностей.

Переносимость кода


JavaScript-приложения могут работать практически везде: в браузерах, на серверах, даже во встраиваемых системах.

WebAssembly спроектирован с учётом безопасности и возможности переносимости кода. Этим он очень похож на JavaScript. Он будет работать в любом окружении, поддерживающем wasm, то есть, например, в любом браузере.

В плане переносимости перед WebAssembly стоят те же цели, которых в своё время пытался достичь Java посредством апплетов.

Итоги


В ранних версиях WebAssembly особое внимание уделялось тяжёлым вычислениям, например, математическим. Очевидная область применения таких вычислений — игры, в которых приходится работать с мириадами пикселей. Подобные приложения можно писать на C++/Rust с использованием привычных методов работы с OpenGL и компилировать то, что получится, в wasm. После чего всё это будет работать в браузере. В качестве примера откройте эту ссылку в Firefox. Тут применяется Unreal Engine.

Ещё один вариант использования WebAssembly, ориентированный на повышение производительности веб-приложений, заключается в реализации с использованием этой технологии библиотек, выполняющих ресурсоёмкие вычисления, например — это библиотеки для обработки изображений.

Использование wasm может довольно серьёзно снизить потребление энергии аккумуляторов на мобильных устройствах (конечно, зависит это и от движка), так как большинство вспомогательных операций по подготовке программы к выполнению будет выполнено в ходе статической компиляции кода.

Ожидается, что в будущем у нас появится возможность использовать бинарные wasm-файлы, даже не занимаясь написанием кода, который в них компилируется. В NPM можно найти проекты, которые реализуют такой подход.

Можно ли говорить о том, что wasm заменит JS? На данном этапе развития технология — определённо нельзя. Например, если речь идёт о работе с DOM или об использовании API платформы, на которой выполняется код, у JavaScript пока нет альтернативы, так как эти API доступны из JS-программ напрямую, без добавления дополнительных уровней абстракции.

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

Предыдущие части цикла статей:

Часть 1: Как работает JS: обзор движка, механизмов времени выполнения, стека вызовов
Часть 2: Как работает JS: о внутреннем устройстве V8 и оптимизации кода
Часть 3: Как работает JS: управление памятью, четыре вида утечек памяти и борьба с ними
Часть 4: Как работает JS: цикл событий, асинхронность и пять способов улучшения кода с помощью async / await
Часть 5: Как работает JS: WebSocket и HTTP/2+SSE. Что выбрать?

Уважаемые читатели! Планируете ли вы пользоваться WebAssembly в своих проектах?

Чем дальше web, тем больше JavaScript-а

Чем дальше web, тем больше JavaScript-а

От автора: «Что нужно знать, чтобы реализовать такое, как тут (ссылка)?» — именно такой вопрос часто встречается на нашем форуме в службе поддержки или приходит к нам на e-mail.

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

В данной статье я расскажу вам о JavaScript — скриптовом языке, предназначенном для создания интерактивных веб-страниц, и о том, что можно делать с помощью JS. Мы рассмотрим примеры использования JavaScript и узнаем, чем он может быть нам полезен.

Что можно делать, используя JavaScript?

Изменять страницу, писать на ней текст, добавлять и удалять теги, менять стили элементов.

Реагировать на события: скрипт может ждать, пока что-нибудь случится (клик/наведение мыши, окончание загрузки страницы) и реагировать на это выполнением функции.
Например, по наведению мыши на ссылку или картинку можно показывать всплывающую подсказку. По клику мыши можно переключать содержимое блока. По окончании загрузки страницы — показывать рекламное попап-окно. Можно изменять внешний вид страницы в зависимости от времени суток.

Чем дальше web, тем больше JavaScript-а

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

Выполнять запросы к серверу и загружать данные без перезагрузки страницы.
Например, если пользователь оставил комментарий на сайте или в гостевой книге, то этот комментарий сразу же отобразится без перезагрузки страницы. Так же можно закачивать файлы на сервер, показывая при этом в процентах ход выполнения загрузки.

Устанавливать и считывать cookie, валидировать данные, выводить сообщения и многое другое.
Например, при первом посещении сайта пользователю показывается попап-окно и устанавливается cookie. А при последующих посещениях этого ресурса попап-окно не показывается, потому что cookie уже установлены.
Также можно проверять корректность введенного e-mail, проверять на соответствие нужному формату введенный номер телефона и сразу выводить сообщение о правильности или неправильности введенных данных.

Чем дальше web, тем больше JavaScript-а

Примеры использования JavaScript

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

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

Что это дает нам?

1. Удобная многоуровневая навигация

Чем дальше web, тем больше JavaScript-а

Использование JavaScript позволяет делать компактными многоуровневые меню, многоуровневую навигацию в side-bar-ах. Подпункты меню открываются либо по клику, либо по наведению мыши.

Во многих интернет-магазинах есть боковая выпадающая навигация. Рассмотрим для примера shop.by. Представьте, насколько бы она растянулась вниз, если бы подпункты не выпадали по наведению или по клику, а были видны все сразу!

2. Использование галерей и слайдеров дает нам возможность показать фотографии, картинки дополнительных видов товаров, удобно и компактно расположить портфолио фотографа.

Чем дальше web, тем больше JavaScript-а

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее

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

Сколько бы понадобилось места для галереи, представленной на картинке ниже?

Чем дальше web, тем больше JavaScript-а

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

Нужно отметить, что на многих сайтах часть виджетов можно просто удалить, потому что никакого смысла от них нет, а место они занимают.

Но что делать, если все-таки нужно компактно вместить много виждетов?

Чем дальше web, тем больше JavaScript-а

Тут на помощь приходит решение JavaScript с «табами».

С их помощью можно хорошо вместить все виджеты в боковых колонках сайта. Для лучшего восприятия можно группировать виджеты в «табы».

Например, в один «таб» можно поместить виджеты социальных сетей, во второй — категории и архивы и т.д. Это позволит сэкономить место и сделает сайт более удобным для использования.

4. Используя JavaScript, можно также существенно улучшить страницу контактов для вашего сайта или сайтов ваших клиентов.

встроить подсказки в поля форм;

проверять вводимые в поля форм данные и выводить сообщения об ошибках;

отправлять данные формы без перезагрузки страницы;

разместить карту с маршрутом.

Чем дальше web, тем больше JavaScript-а

5. Для тех, кто размещает на сайте табличные данные, очень полезным будет использование сортировки данных в таблице.

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

Чем дальше web, тем больше JavaScript-а

Также, используя JavaScript, можно делать всевозможные эффекты на сайте — такие как плавное выскальзывание элементов, их перемещение, постепенное появление и исчезновение и все то, на что хватит вашей фантазии.

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

Заключение

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

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

Надеюсь, статья вам понравилась, и вы узнали из нее о новых возможностях, которые можно реализовать, благодаря JS.

А вы используете JavaScript на своих сайтах? Какие у вас основные трудности при использовании JavaScript?

Расскажите об этом в комментариях к статье.

P.S. «Чем дальше web, тем больше JavaScript-а».

Чем дальше web, тем больше JavaScript-а

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Узнать подробнее Чем дальше web, тем больше JavaScript-а

JavaScript. Быстрый старт

Изучите основы JavaScript на практическом примере по созданию веб-приложения

Смотреть

функции / RUVDS.com corporate blog / Habr

Сегодня публикуем четвёртую часть перевода руководства по JavaScript, которая посвящена функциям.

→ Часть 1: первая программа, особенности языка, стандарты
→ Часть 2: стиль кода и структура программ
→ Часть 3: переменные, типы данных, выражения, объекты
→ Часть 4: функции
→ Часть 5: массивы и циклы
→ Часть 6: исключения, точка с запятой, шаблонные литералы
→ Часть 7: строгий режим, ключевое слово this, события, модули, математические вычисления
→ Часть 8: обзор возможностей стандарта ES6
→ Часть 9: обзор возможностей стандартов ES7, ES8 и ES9

Функции в JavaScript


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

Функция — это самостоятельный блок кода, который можно, один раз объявив, вызывать столько раз, сколько нужно. Функция может, хотя это и необязательно, принимать параметры. Функции возвращают единственное значение.

Функции в JavaScript являются объектами, если точнее, то они являются объектами типа Function. Их ключевое отличие от обычных объектов, дающее им те исключительные возможности, которыми они обладают, заключается в том, что функции можно вызывать.

Кроме того, функции в JavaScript называют «функциями первого класса» так как их можно назначать переменным, их можно передавать другим функциям в качестве аргументов, их можно возвращать из других функций.

Сначала рассмотрим особенности работы с функциями и соответствующие синтаксические конструкции, которые существовали в языке до появления стандарта ES6 и актуальны до сих пор.

Вот как выглядит объявление функции (function declaration).

function doSomething(foo) {
  //сделать что-нибудь
}

В наши дни такие функции называют «обычными», отличая их от «стрелочных» функций, которые появились в ES6.

Функцию можно назначить переменной или константе. Такая конструкция называется функциональным выражением (function expression).

const doSomething = function(foo) {
  //сделать что-нибудь
}

Можно заметить, что в вышеприведённом примере функция назначена константе, но сама она имени не имеет. Такие функции называют анонимными. Подобным функциям можно назначать имена. В таком случае речь идёт об именованном функциональном выражении (named function expression).
const doSomething = function doSomFn(foo) {
  //сделать что-нибудь
}

Использование таких выражений повышает удобство отладки (в сообщениях об ошибках, где проводится трассировка стека, видно имя функции). Имя функции в функциональном выражении может понадобиться и для того, чтобы функция могла бы сама себя вызывать, без чего не обойтись при реализации рекурсивных алгоритмов.

В стандарте ES6 появились стрелочные функции (arrow function), которые особенно удобно использовать в виде так называемых «встроенных функций» (inline function) — в роли аргументов, передаваемых другим функциям (коллбэков).

const doSomething = foo => {
  //сделать что-нибудь
}

Стрелочные функции, помимо того, что структуры, используемые для их объявления, получаются более компактными, чем при использовании обычных функций, отличаются от них некоторыми важными особенностями, о которых мы поговорим ниже.

Параметры функций


Параметры представляют собой переменные, которые задаются на этапе объявления функции и будут содержать передаваемые ей значения (эти значения называют аргументами). Функции в JavaScript могут либо не иметь параметров, либо иметь один или несколько параметров.
const doSomething = () => {
  //сделать что-нибудь
}
const doSomethingElse = foo => {
  //сделать что-нибудь
}
const doSomethingElseAgain = (foo, bar) => {
  //сделать что-нибудь
}

Здесь показано несколько примеров стрелочных функций.

Начиная со стандарта ES6 у функций могут быть так называемые «параметры по умолчанию» (default parameters).

const doSomething = (foo = 1, bar = 'hey') => {
  //сделать что-нибудь
}

Они представляют собой стандартные значения, задаваемые параметрам функций в том случае, если при её вызове значения некоторых параметров не задаются. Например, функцию, показанную выше, можно вызвать как с передачей ей всех двух принимаемых ей параметров, так и другими способами.
doSomething(3)
doSomething()

В ES8 появилась возможность ставить запятую после последнего аргумента функции (это называется trailing comma). Эта возможность позволяет повысить удобство редактирования кода при использовании систем контроля версий в ходе разработки программ. Подробности об этом можно почитать здесь и здесь.

Передаваемые функциям аргументы можно представлять в виде массивов. Для того чтобы разобрать эти аргументы можно воспользоваться оператором, который выглядит как три точки (это — так называемый «оператор расширения» или «оператор spread»). Вот как это выглядит.

const doSomething = (foo = 1, bar = 'hey') => {
  //сделать что-нибудь
}
const args = [2, 'ho!']
doSomething(...args)

Если функции нужно принимать много параметров, то запомнить порядок их следования может быть непросто. В таких случаях используются объекты с параметрами и возможности по деструктурированию объектов ES6.
const doSomething = ({ foo = 1, bar = 'hey' }) => {
  //сделать что-нибудь
  console.log(foo) // 2
  console.log(bar) // 'ho!'
}
const args = { foo: 2, bar: 'ho!' }
doSomething(args)

Этот приём позволяет, описывая параметры в виде свойств объекта и передавая функции объект, получить в функции доступ к параметрам по их именам без использования дополнительных конструкций. Подробнее об этом приёме можно почитать здесь.

Значения, возвращаемые из функций


Все функции возвращают некое значение. Если команда возврата явно не задана — функция возвратит undefined.
const doSomething = (foo = 1, bar = 'hey') => {
  //сделать что-нибудь
}

console.log(doSomething())

Выполнение функции завершается либо после того, как оказывается выполненным весь код, который она содержит, либо после того, как в коде встречается ключевое слово return. Когда в функции встречается это ключевое слово, её работа завершается, а управление передаётся в то место, откуда была вызвана функция.

Если после ключевого слова return указать некое значение, то это значение возвращается в место вызова функции в качестве результата выполнения этой функции.

const doSomething = () => {
  return 'test'
}
const result = doSomething() // result === 'test'

Из функции можно возвращать лишь одно значение. Для того чтобы получить возможность возврата нескольких значений, возвращать их можно либо в виде объекта, используя объектный литерал, либо в виде массива, а при вызове функции применять конструкцию деструктурирующего присваивания. Имена параметров при этом сохраняются. При этом, если нужно работать с объектом или массивом, возвращённым из функции, именно в виде объекта или массива, можно обойтись без деструктурирующего присваивания.
const doSomething = () => {
  return ['Roger', 6]
}

const [ name, age ] = doSomething()
console.log(name, age) //Roger 6

Конструкцию const [ name, age ] = doSomething() можно прочитать следующим образом: «объявить константы name и age и присвоить им значения элементов массива, который возвратит функция».
Вот как то же самое выглядит с использованием объекта.
const doSomething = () => {
  return {name: 'Roger', age: 6}
}

const { name, age } = doSomething()
console.log(name, age) //Roger 6

Вложенные функции


Функции можно объявлять внутри других функций.
const doSomething = () => {
  const doSomethingElse = () => {}
  doSomethingElse()
  return 'test'
}

doSomething()

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

Методы объектов


Когда функции используются в качестве свойств объектов, такие функции называют методами объектов.
const car = {
  brand: 'Ford',
  model: 'Fiesta',
  start: function() {
    console.log(`Started`)
  }
}
car.start()

Ключевое слово this


Если сравнить стрелочные и обычные функции, используемые в качестве методов объектов, можно обнаружить их важное различие, заключающееся в смысле ключевого слова this. Рассмотрим пример.
const car = {
  brand: 'Ford',
  model: 'Fiesta',
  start: function() {
    console.log(`Started ${this.brand} ${this.model}`)
  },
  stop: () => {
    console.log(`Stopped ${this.brand} ${this.model}`)
  }
}
car.start() //Started Ford Fiesta
car.stop() //Stopped undefined undefined

Как видно, вызов метода start() приводит ко вполне ожидаемому результату, а вот метод stop() явно работает неправильно.

Происходит это из-за того, что ключевое слово this по-разному ведёт себя при его использовании в стрелочных и обычных функциях. А именно, ключевое слово this в стрелочной функции содержит ссылку на контекст, включающий в себя функцию. В данном случае, если речь идёт о браузере, этим контекстом является объект window.

Вот как выглядит выполнение такого кода в консоли браузера.

const test = {
  fn: function() {
    console.log(this)
  },
  arrFn: () => {
    console.log(this)
  }
}

test.fn()
test.arrFn()


Особенности ключевого слова this в обычных и стрелочных функциях

Как можно заметить, обращение к this в обычной функции означает обращение к объекту, а this в стрелочной функции указывает на window.

Всё это означает, что стрелочные функции не подходят на роль методов объектов и конструкторов (если попытаться использовать стрелочную функцию в роли конструктора — будет выдана ошибка TypeError).

Немедленно вызываемые функциональные выражения


Немедленно вызываемое функциональное выражение (Immediately Invoked Function Expression, IIFE) — это функция, которая автоматически вызывается сразу после её объявления.
;(function () {
  console.log('executed')
})()

Точка с запятой перед IIFE необязательна, но её использование позволяет застраховаться от ошибок, связанных с автоматической расстановкой точек с запятой.

В вышеприведённом примере в консоль попадёт слово executed, после чего IIFE завершит работу. IIFE, точно так же как и другие функции, могут возвращать результаты своей работы.

const something = (function () {
  return 'IIFE'
})()

console.log(something)

После выполнения этого простого примера в консоль попадёт строка IIFE, которая оказалась в константе something после выполнения немедленно вызываемого функционального выражения. Может показаться, что особой пользы от такой конструкции нет. Однако если в IIFE выполняются некие сложные вычисления, которые нужно выполнить лишь однажды, после чего соответствующие механизмы оказываются ненужными — полезность IIFE оказывается очевидной. А именно, при таком подходе после выполнения IIFE в программе будет доступен лишь возвращённый функцией результат. Кроме того, можно вспомнить, что функции способны возвращать другие функции и объекты. Речь идёт о замыканиях, о них мы поговорим ниже.

Поднятие функций


Перед выполнением JavaScript-кода производится его реорганизация. Мы уже говорили о механизме поднятия (hoisting) переменных, объявленных с использованием ключевого слова var. Похожий механизм действует и при работе с функциями. А именно, речь идёт о том, что объявления функций в ходе обработки кода перед его выполнением перемещаются в верхнюю часть их области видимости. В результате, например, оказывается, что вызвать функцию можно до её объявления.
doSomething() //did something
function doSomething() {
  console.log('did something')
}

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

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

doSomething() //TypeError
var doSomething = function () {
  console.log('did something')
}

В данном случае оказывается, что хотя объявление переменной doSomething и поднимается в верхнюю часть области видимости, это не относится к операции присваивания.
Если вместо var в похожей ситуации использовать ключевые слова let или const, такой код тоже работать не будет, правда, система выдаст другое сообщение об ошибке (ReferenceError а не TypeError), так как при использовании let и const объявления переменных и констант не поднимаются.

Стрелочные функции


Сейчас мы подробнее поговорим о стрелочных функциях, с которыми мы уже встречались. Их можно считать одним из наиболее значительных новшеств стандарта ES6, они отличаются от обычных функций не только внешним видом, но и особенностями поведения. В наши дни они используются чрезвычайно широко. Пожалуй, нет ни одного современного проекта, где они не использовались бы в подавляющем большинстве случаев. Можно сказать, что их появление навсегда изменило и внешний вид JS-кода и особенности его работы.

С чисто внешней точки зрения синтаксис объявления стрелочных функций оказывается компактнее синтаксиса обычных функций. Вот объявление обычной функции.

const myFunction = function () {
  //...
}

Вот объявление стрелочной функции, которое, в целом, если не учитывать особенности стрелочных функций, аналогично предыдущему.
const myFunction = () => {
  //...
}

Если тело стрелочной функции содержит лишь одну команду, результат которой возвращает эта функция, его можно записать без фигурных скобок и без ключевого слова return. Например, такая функция возвращает сумму переданных ей аргументов.
const myFunction = (a,b) => a + b
console.log(myFunction(1,2)) //3

Как видите, параметры стрелочных функций, как и в случае с обычными функциями, описывают в скобках. При этом, если такая функция принимает всего один параметр, его можно указать без скобок. Например, вот функция, которая возвращает результат деления переданного ей числа на 2.
const myFunction = a => a / 2
console.log(myFunction(8)) //4

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

▍Неявный возврат результатов работы функции


Мы уже касались этой особенности стрелочных функций, но она настолько важна, что её следует обсудить подробнее. Речь идёт о том, что однострочные стрелочные функции поддерживают неявный возврат результатов своей работы. Пример возврата примитивного значения из однострочной стрелочной функции мы уже видели. Как быть, если такая функция должна возвратить объект? В таком случае фигурные скобки объектного литерала могут запутать систему, поэтому в теле функции используются круглые скобки.
const myFunction = () => ({value: 'test'})

const obj = myFunction() 
console.log(obj.value) //test

▍Ключевое слово this и стрелочные функции


Выше, когда мы рассматривали особенности ключевого слова this, мы сравнивали обычные и стрелочные функции. Этот раздел призван обратить ваше внимание на важность их различий. Ключевое слово this, само по себе, может вызывать определённые сложности, так как оно зависит и от контекста выполнения кода, и от того, включен или нет строгий режим (strict mode).

Как мы уже видели, при использовании ключевого слова this в методе объекта, представленного обычной функцией, this указывает на объект, которому принадлежит метод. В таком случае говорят о привязке ключевого слова this к значению, представляющему собой контекст выполнения функции. В частности, если функция вызвана в виде метода объекта, то ключевое слово this привязано к этому объекту.

В случае же со стрелочными функциями оказывается так, что в них привязка this не выполняется, они пользуются ключевым словом this из содержащих их областей видимости. В результате их не рекомендуется использовать в качестве методов объектов.

Та же самая проблема возникает и при использовании функций в качестве обработчиков событий элементов DOM. Например, HTML-элемент button используют для описания кнопок. Событие click вызывается при щелчке мышью по кнопке. Для того чтобы отреагировать на это событие в коде, нужно сначала получить ссылку на соответствующий элемент, а потом назначить ему обработчик события click в виде функции. В качестве такого обработчика можно использовать и обычную функцию, и стрелочную. Но, если в обработчике событий нужно обращаться к тому элементу, для которого оно вызвано (то есть — к this), стрелочная функция тут не подойдёт, так как доступное в ней значение this указывает на объект window. Для того чтобы проверить это на практике, создайте HTML-страницу, код которой показан ниже, и понажимайте на кнопки.

<!DOCTYPE html>
<html>
  <body>
  
    <button>Function</button>
    <button>Arrow function</button>

    <script>
      const f = document.getElementById("fn")
      f.addEventListener('click', function () {
          alert(this === f)
      })

      const af = document.getElementById("arrowFn")
      af.addEventListener('click', () => {
          alert(this === window)
      })
    </script>
  </body>
</html>

В данном случае при нажатии на эти кнопки будут появляться окна, содержащие true. Однако в обработчике события click кнопки с идентификатором fn проверяется равенство this самой кнопке, а в кнопке с идентификатором arrowFn проверяется равенство this и объекта window.

В результате, если в обработчике события HTML-элемента нужно обращаться к this, стрелочная функция для оформления такого обработчика не подойдёт.

Замыкания


Замыкания — это важная концепция в JavaScript. Фактически, если вы писали JS-функции, то вы пользовались и замыканиями. Замыкания применяются в некоторых паттернах проектирования — в том случае, если нужно организовать строгий контроль доступа к неким данным или функциям.

Когда функция вызывается, у неё есть доступ ко всему тому, что находится во внешней по отношению к ней области видимости. Но к тому, что объявлено внутри функции, извне доступа нет. То есть, если в функции была объявлена некая переменная (или другая функция), они недоступны внешнему коду ни во время выполнения функции, ни после завершения её работы. Однако если из функции возвратить другую функцию, то эта новая функция будет иметь доступ ко всему тому, что было объявлено в исходной функции. При этом всё это будет скрыто от внешнего кода в замыкании.

Рассмотрим пример. Вот функция, которая принимает имя собаки, после чего выводит его в консоль.

const bark = dog => {
  const say = `${dog} barked!`
  ;(() => console.log(say))()
}
bark(`Roger`) // Roger barked!

Значение, возвращаемое этой функцией нас пока не интересует, текст выводится в консоль с помощью IIFE, что в данном случае особой роли не играет, однако, это поможет нам увидеть связь между этой функцией и её вариантом, в котором, вместо вызова функции, которая выводит текст в консоль, мы эту функцию из переписанной функции bark() возвратим.
const prepareBark = dog => {
  const say = `${dog} barked!`
  return () => console.log(say)
}
const bark = prepareBark(`Roger`)
bark() // Roger barked!

Результат работы код в двух случаях оказывается одинаковым. Но во втором случае то, что было передано исходной функции при её вызове (имя собаки, Roger), хранится в замыкании, после чего используется другой функцией, возвращённой из исходной.

Проведём ещё один эксперимент — создадим, пользуясь исходной функцией, две новых, для разных собак.

const prepareBark = dog => {
  const say = `${dog} barked!`
  return () => {
    console.log(say)
  }
}
const rogerBark = prepareBark(`Roger`)
const sydBark = prepareBark(`Syd`)
rogerBark()
sydBark()

Этот код выведет следующее.
Roger barked!
Syd barked!

Оказывается, что значение константы say привязано к функции, которая возвращена из функции prepareBark().

Обратите внимание на то, что say, при повторном вызове prepareBark(), получает новое значение, при этом значение, записанное в say при первом вызове prepareBark(), не меняется. Речь идёт о том, что при каждом вызове этой функции создаётся новое замыкание.

Итоги


Сегодня мы говорили об обычных и стрелочных функциях, об особенностях их объявления и использования, о том, как, в разных ситуациях ведёт себя ключевое слово this, и о замыканиях. В следующий раз обсудим массивы и циклы.

Уважаемые читатели! Как вы относитесь к стрелочным функциям в JavaScript?

Введение в JavaScript

Что такое JavaScript

Последнее обновление: 1.11.2015

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

JavaScript был создан в 1995 году в компании Netscape в качестве языка сценариев в браузере Netscape Navigator 2. Первоначально язык назывался LiveScript, но на волне популярности в тот момент другого языка Java LiveScript был переименован в JavaScript. Однако данный момент до сих пор иногда приводит к некоторой путанице: некоторые начинающие разработчики считают, что Java и JavaScript чуть ли не один и тот же язык. Нет, это абсолютно два разных языка, и они связаны только по названию.

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

Однако развитие веб-среды, появление HTML5 и технологии Node.js открыло перед JavaScript гораздо большие горизонты. Сейчас JavaScript продолжает использоваться для создания веб-сайтов, только теперь он предоставляет гораздо больше возможностей.

Также он применяется как язык серверной стороны. То есть если раньше JavaScript применялся только на веб-странице, а на стороне сервера нам надо было использовать такие технологии, как PHP, ASP.NET, Ruby, Java, то сейчас благодаря Node.js мы можем обрабатывать все запросы к серверу также с помощью JavaScript.

В последнее время переживает бум сфера мобильной разработки. И JavaScript опять же не остается в стороне: увеличение мощности устройств и повсеместное распространение стандарта HTML5 привело к тому, что для создания приложений для смартфонов и планшетов мы также можем использовать JavaScript.

Более того благодаря выходу нового семейства операционных систем Windows: Windows 8 / 8.1 / 10 — можно использовать данный язык программирования для разработки приложений для этих операционных систем. То есть JavaScript уже перешагнул границы веб-браузера, которые ему были очерчены при его создании.

И что вообще раньше казалось фантастикой, но сегодня стало реальностью — javascript может использоваться для набирающего популярность направления разработки для IoT(Internet of Things или Интернет вещей). То есть JavaScript можно использовать для программирования самых различных «умных» устройств, которые взаимодействуют с интернетом.

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

С самого начала существовало несколько веб-браузеров (Netscape, Internet Explorer), которые предоставляли различные реализации языка. И чтобы свести различные реализации к общему стержню и стандартизировать язык под руководством организации ECMA был разработан стандарт ECMAScript. В принципе сами термины JavaScript и ECMAScript являются во многом взаимозаменяемыми и относятся к одному и тому же языку.

К настоящему времени ECMA было разработано несколько стандартов языка, которые отражают его развитие. Последним принятым на сегодняшний день стандартом является ECMAScript 2015 (ES 6). Но надо сказать, что реализация этого стандарта в распространенных веб-браузерах очень далека до завершения, и, возможно, на его полное внедрение уйдет несколько лет. Поэтому в данном руководстве рассматриваются преимущественно стандарт ES5 и те функциональные возможности, которые уже доступны во всех популярных браузерах.

JavaScript является интерпретируемым языком. Это значит, что код на языке JavaScript выполняется с помощью интерпретатора. Интерпретатор получает инструкции языка JavaScript, которые определены на веб-странице, выполняет их (или интерпретирует).

Средства разработки

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

Также существуют различные среды разработки, которые поддерживают JavaScript и облегчают разработку на этом языке, например, Visual Studio, WebStorm, Netbeans и так далее. При желании можно использовать также эти среды разработки.

Итак, приступим к созданию первой программы.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *