reduce/reduceRight
Метод «arr.reduce(callback)» используется для последовательной обработки каждого элемента массива с сохранением промежуточного результата.
Это один из самых сложных методов для работы с массивами. Но его стоит освоить, потому что временами с его помощью можно в несколько строк решить задачу, которая иначе потребовала бы в разы больше места и времени.
Метод используется для вычисления на основе массива какого-либо единого значения, иначе говорят «для свёртки массива». Чуть далее мы разберём пример для вычисления суммы.
Он применяет функцию по очереди к каждому элементу массива слева направо, сохраняя при этом промежуточный результат.
Аргументы функции :
- – последний результат вызова функции, он же «промежуточный результат».
- – текущий элемент массива, элементы перебираются по очереди слева-направо.
- – номер текущего элемента.
- – обрабатываемый массив.
Кроме , методу можно передать «начальное значение» – аргумент . Если он есть, то на первом вызове значение будет равно , а если у нет второго аргумента, то оно равно первому элементу массива, а перебор начинается со второго.
Проще всего понять работу метода на примере.
Например, в качестве «свёртки» мы хотим получить сумму всех элементов массива.
Вот решение в одну строку:
Разберём, что в нём происходит.
При первом запуске – исходное значение, с которого начинаются вычисления, равно нулю (второй аргумент ).
Сначала анонимная функция вызывается с этим начальным значением и первым элементом массива, результат запоминается и передаётся в следующий вызов, уже со вторым аргументом массива, затем новое значение участвует в вычислениях с третьим аргументом и так далее.
Поток вычислений получается такой
В виде таблицы где каждая строка – вызов функции на очередном элементе массива:
результат | |||
---|---|---|---|
первый вызов | |||
второй вызов | |||
третий вызов | |||
четвёртый вызов | |||
пятый вызов |
Как видно, результат предыдущего вызова передаётся в первый аргумент следующего.
Кстати, полный набор аргументов функции для включает в себя , то есть номер текущего вызова и весь массив , но здесь в них нет нужды.
Посмотрим, что будет, если не указать в вызове :
Результат – точно такой же! Это потому, что при отсутствии в качестве первого значения берётся первый элемент массива, а перебор стартует со второго.
Таблица вычислений будет такая же, за вычетом первой строки.
Метод arr.reduceRight работает аналогично, но идёт по массиву справа-налево.
1.3 Вещественные типы
Среди примитивных типов также есть два вещественных. Хотя это не совсем точное название. Официально они называются числа с плавающей точкой — floating point numbers. Название происходит из стандарта, когда целую и дробную часть числа разделяет точка (а не запятая).
Полезно:
В каждой стране свои стандарты для записи чисел (внезапно!).
Многие из нас привыкли писать точки для разделения тысяч и запятую для отделения дробной части: например, мы бы записали так . А вот в США, где жили создатели Java, принят другой стандарт:
В Java есть два примитивных типа с плавающей точкой: и .
Как мы уже говорили ранее, эти типы внутри устроены специфическим образом: фактически внутри каждой переменной этих типов находится не одно число, а два:
Например, дробное число можно представить как . Поэтому в памяти оно будет представлено как два числа (мантисса — значащая часть числа) и (экспонента — степень десятки)
Тип
Само название типа происходит от floating point number. Размер этого типа совсем небольшой — всего 4 байта (32 бита), но он может хранить значения от до . Под мантиссу отдается 24 бита, под экспоненту — 8 бит. Этот тип способен хранить всего 8 значащих цифр.
Такой подход позволяет хранить гораздо большие числа, чем , используя все те же 4 байта. Но при этом мы жертвуем точностью. Часть памяти расходуется на хранение мантиссы, поэтому такие числа хранят всего 6-7 знаков после запятой, остальные отбрасываются.
Пример:
Код | Значение переменной |
---|---|
Как видите, основной недостаток этого типа — очень маленькое количество значащих цифр и потеря точности уже в восьмой цифре. Поэтому тип не сильно популярен среди Java-программистов.
Тип
Тип является стандартным типом с плавающей точкой. Его название происходит от double floating point. Его еще называют числом с плавающей точкой двойной точности. Все вещественные литералы по умолчанию имеют тип .
Этот тип занимает 8 байт памяти (64 бита) и может хранить значения от до . Важным моментом является то, что под его мантиссу отводится 53 бита, а остальные 11 – под экспоненту.
Это позволяет хранить 15-17 значащих цифр.
Пример:
Код | Значение переменной |
---|---|
Такая точность, особенно в сравнении с типом , является определяющей: 99% всех операций с вещественными числами выполняются с типом .
Под экспоненту выделяется бит, что позволяет хранить степень десятки от до (степень двойки — от до ). Тип легко может хранить число с сотней нулей после запятой:
Код | Значение переменной |
---|---|
Как бесплатно перенести свои любимые треки в Spotify, используя Javascript
Все любители музыки в России с нетерпением ждали выхода Spotify на наш рынок. Когда наконец это случилось, перед пользователями встала проблема переноса музыки из других сервисов. Лично у меня за годы накопилась огромная коллекция музыки на разных платформах: Яндекс.Музыка, ВКонтакте, личная коллекция на жёстком диске и облако на Яндекс.Диске.
Сначала я думал воспользоваться сервисами вроде Soundiiz и TuneMyMusic. Но вдохновившись статьёй об использовании Python в тех же целях, мне стало интересно решить эту задачку с помощью Javascript. Далее я опишу ряд простых шагов с исходным кодом, которые помогут перенести вашу музыку из разных источников в Spotify.
Другие технологии. Альтернативы javascript.
Возможности javascript в некоторых областях, к сожалению, ограничены.
Поэтому используются альтернативные технологии.
Java — по сравнению с javascript, java-applet’ы тяжелые, долго загружаются, но могут все. Они, как правило, используются там, где требуется почти-десктоп приложение. Очень сильно java’у потеснила технология Flash.
Java — один из наиболее распространенных в мире языков. На нем существует громадное количество библиотек, с помощью которых можно описывать сложные интерфейсы и алгоритмы. Но на интернет-сайтах это нужно редко.
Flash изначально появился как кроссбраузерная платформа и язык для мультимедии, для оживления веба красочной анимацией, аудио и видео. Но не только это вкусно в технологии Flash.
- Мощные средства для создания сетевых соединений(сокеты)
- Объекты для работы с мультимедиа: изображениями, аудио, видео
- Внутреннее хранилище объектов, которые не посылаются на сервер при каждом запросе, как куки.
- Удобные графические средства разработки для Flash
Ну и для баланса — недостатки, по сравнению с javascript.
- Отдельный контейнер. Например, нельзя выделить участок текста, частично находящегося в контейнере Flash.
- Плохо индексируется поисковиками. Поисковики ходят по HTML-ссылкам, но(пока?) не кликают по ссылкам внутри Flash-приложения.
Из Flash можно легко вызвать javascript. Наоборот — сложнее, но тоже возможно, поэтому целесообразно знать обе технологии и применять их вместе.
Эти технологии призваны дополнять javascript в области коммуникации и построения интерфейсов.
Пока они все далеки по распространенности от javascript и flash.
- JavaFX — «легкая» надстройка над Java, будет работать только с Java на компьютере клиента.
- XUL — язык описания интерфейсов, удобен если писать планируете только под Mozilla. Также используется для написания десктоп-приложений.
- Silverlight — конкурент Flash от Microsoft на основе .NET. Другими OS, кроме Windows, поддерживается слабо. Не имеет широкого распространения.
- vbscript — попытка Microsoft сделать подобие javascript на основе Visual Basic. Не развивается, сильно уступает по возможностям, и, как следствие — практически не используется в современном веб-программировании.
ИЛИ «||» находит первое истинное значение
Описанная выше логика соответствует традиционной. Теперь давайте поработаем с «дополнительными» возможностями JavaScript.
Расширенный алгоритм работает следующим образом.
При выполнении ИЛИ || с несколькими значениями:
Оператор выполняет следующие действия:
- Вычисляет операнды слева направо.
- Каждый операнд конвертирует в логическое значение. Если результат , останавливается и возвращает исходное значение этого операнда.
- Если все операнды являются ложными (), возвращает последний из них.
Значение возвращается в исходном виде, без преобразования.
Другими словами, цепочка ИЛИ возвращает первое истинное значение или последнее, если такое значение не найдено.
Например:
Это делает возможным более интересное применение оператора по сравнению с «чистым, традиционным, только булевым ИЛИ».
-
Получение первого истинного значения из списка переменных или выражений.
Представим, что у нас имеется ряд переменных, которые могут содержать данные или быть . Как мы можем найти первую переменную с данными?
С помощью :
Если бы и , и были ложными, в качестве результата мы бы наблюдали .
-
Сокращённое вычисление.
Операндами могут быть как отдельные значения, так и произвольные выражения. ИЛИ вычисляет их слева направо. Вычисление останавливается при достижении первого истинного значения. Этот процесс называется «сокращённым вычислением», поскольку второй операнд вычисляется только в том случае, если первого недостаточно для вычисления всего выражения.
Это хорошо заметно, когда выражение, указанное в качестве второго аргумента, имеет побочный эффект, например, изменение переменной.
В приведённом ниже примере не изменяется:
Если бы первый аргумент имел значение , то приступил бы к вычислению второго и выполнил операцию присваивания:
Присваивание – лишь один пример. Конечно, могут быть и другие побочные эффекты, которые не проявятся, если вычисление до них не дойдёт.
Как мы видим, этот вариант использования является «аналогом «. Первый операнд преобразуется в логический. Если он оказывается ложным, начинается вычисление второго.
В большинстве случаев лучше использовать «обычный» , чтобы облегчить понимание кода, но иногда это может быть удобно.
Изучаем хук useRef в React.js
Перевод
Доброго времени суток, друзья.
Представляю вашему вниманию перевод небольшой заметки про использование хука useRef в React.
Хук useState позволяет добавлять состояние в функциональные компоненты. Данный хук предоставляет возможность передавать значение, сохраняемое при повторном рендеринге страницы, а также интерфейс для обновления этого значения и принудительного запуска ререндеринга.
Возможность сохранять значение при ререндеринге обеспечивает динамичность данных, а возможность обновлять значение и запускать повторный рендеринг обеспечивает динамичность пользовательского интерфейса.
Но что если у нас нет необходимости в повторном рендеринге, но при этом нам нужно сохранять значение? В данном случае, нам нужна лишь половина useState:
useState возвращает массив, в котором первым элементом является сохраненное значение, а вторым — функция, запускающая повторный рендеринг.
Нам нужен только первый элемент, поэтому мы добавляем . При запуске usePersistentValue мы получим объект, в свойстве которого будет содержаться сохраненное значение.
Рассмотрим пример.
Основы
XMLHttpRequest имеет два режима работы: синхронный и асинхронный.
Сначала рассмотрим асинхронный, так как в большинстве случаев используется именно он.
Чтобы сделать запрос, нам нужно выполнить три шага:
-
Создать .
-
Инициализировать его.
Этот метод обычно вызывается сразу после . В него передаются основные параметры запроса:
- – HTTP-метод. Обычно это или .
- – URL, куда отправляется запрос: строка, может быть и объект URL.
- – если указать , тогда запрос будет выполнен синхронно, это мы рассмотрим чуть позже.
- , – логин и пароль для базовой HTTP-авторизации (если требуется).
Заметим, что вызов , вопреки своему названию, не открывает соединение. Он лишь конфигурирует запрос, но непосредственно отсылается запрос только лишь после вызова .
-
Послать запрос.
Этот метод устанавливает соединение и отсылает запрос к серверу. Необязательный параметр содержит тело запроса.
Некоторые типы запросов, такие как , не имеют тела. А некоторые, как, например, , используют , чтобы отправлять данные на сервер. Мы позже увидим примеры.
-
Слушать события на , чтобы получить ответ.
Три наиболее используемых события:
- – происходит, когда получен какой-либо ответ, включая ответы с HTTP-ошибкой, например 404.
- – когда запрос не может быть выполнен, например, нет соединения или невалидный URL.
- – происходит периодически во время загрузки ответа, сообщает о прогрессе.
Вот полный пример. Код ниже загружает с сервера и сообщает о прогрессе:
После ответа сервера мы можем получить результат запроса в следующих свойствах :
- Код состояния HTTP (число): , , и так далее, может быть в случае, если ошибка не связана с HTTP.
- Сообщение о состоянии ответа HTTP (строка): обычно для , для , для , и так далее.
- (в старом коде может встречаться как )
- Тело ответа сервера.
Мы можем также указать таймаут – промежуток времени, который мы готовы ждать ответ:
Если запрос не успевает выполниться в установленное время, то он прерывается, и происходит событие .
URL с параметрами
Чтобы добавить к URL параметры, вида , и корректно закодировать их, можно использовать объект URL:
«var» обрабатываются в начале запуска функции
Объявления переменных обрабатываются в начале выполнения функции (или запуска скрипта, если переменная является глобальной).
Другими словами, переменные считаются объявленными с самого начала исполнения функции вне зависимости от того, в каком месте функции реально находятся их объявления (при условии, что они не находятся во вложенной функции).
Т.е. этот код:
…Технически полностью эквивалентен следующему (объявление переменной перемещено в начало функции):
…И даже коду ниже (как вы помните, блочная область видимости игнорируется):
Это поведение называется «hoisting» (всплытие, поднятие), потому что все объявления переменных «всплывают» в самый верх функции.
В примере выше условие никогда не выполнится. Но это никаким образом не препятствует созданию переменной , которая находится внутри него, поскольку объявления «всплывают» в начало функции. Т.е. в момент присвоения значения переменная уже существует.
Объявления переменных «всплывают», но присваивания значений – нет.
Это проще всего продемонстрировать на примере:
Строка состоит из двух действий:
- Объявление переменной
- Присвоение значения в переменную .
Объявление переменной обрабатывается в начале выполнения функции («всплывает»), однако присвоение значения всегда происходит в той строке кода, где оно указано. Т.е. код выполняется по следующему сценарию:
Поскольку все объявления переменных обрабатываются в начале функции, мы можем ссылаться на них в любом месте. Однако, переменные имеют значение до строки с присвоением значения.
В обоих примерах выше вызов происходил без ошибки, потому что переменная уже существовала. Но её значение ещё не было присвоено, поэтому мы получали .
ECMAScript
Стандарт (формальное описание синтаксиса и работы языка) javascript называется ECMAScript. На нем, кстати, основан не только javascript, но и несколько других языков, например ActionScript (Flash).
По ECMAScript есть спецификация, которая подробно описывает синтаксис, управляющие конструкции и базовые объекты языка.
Например, вот скрипт, который работает, используя только ECMAScript. Кстати, поэтому он будет работать и в других языках, основанных на ECMAScript, включая ActionScript:
var max = 5 try { for(var i=0; i<Number.POSITIVE_INFINITY; i++) { if (i>max) throw new Error("failed to reach the stars") } } catch(e) { }
ECMAScript — и правда очень особенный язык. Особенно для тех, кто пришел из PHP, C, Java. В нем особым образом устроены объекты и функции.
Здесь мы пройдем по основным особенностям и отличиям языка.
Уникальность javascript
Прелесть и соль Javascript заключаются всего в нескольких пунктах.
- Полная интеграция с браузером
- Простые вещи делаются просто
- Поддерживается почти везде
Этот компот преимуществ нельзя найти ни в одной из других технологий.
Например, такие технологии как ActiveX, VBScript, XUL — поддерживаются не в каждом браузере (не кросс-браузерны). Такие технологии как Flash, Silverlight, Java — не полностью интегрированы с браузером, работают в своем окружении.
Поэтому Javascript — уникальная технология, и таковой останется. Сейчас она развивается, создается язык Javascript 2 и новый интерпретатор.
Учите javascript.
Как всё устроено, Юникод
Глубокое погружение в тему
Этот раздел более подробно описывает, как устроены строки. Такие знания пригодятся, если вы намерены работать с эмодзи, редкими математическими символами, иероглифами, либо с ещё какими-то редкими символами.
Если вы не планируете их поддерживать, эту секцию можно пропустить.
Многие символы возможно записать одним 16-битным словом: это и буквы большинства европейских языков, и числа, и даже многие иероглифы.
Но 16 битов — это 65536 комбинаций, так что на все символы этого, разумеется, не хватит. Поэтому редкие символы записываются двумя 16-битными словами — это также называется «суррогатная пара».
Длина таких строк — :
Обратите внимание, суррогатные пары не существовали, когда был создан JavaScript, поэтому язык не обрабатывает их адекватно!
Ведь в каждой из этих строк только один символ, а показывает длину .
и — два редких метода, правильно работающие с суррогатными парами, но они и появились в языке недавно. До них были только String.fromCharCode и str.charCodeAt. Эти методы, вообще, делают то же самое, что , но не работают с суррогатными парами.
Получить символ, представленный суррогатной парой, может быть не так просто, потому что суррогатная пара интерпретируется как два символа:
Части суррогатной пары не имеют смысла сами по себе, так что вызовы в этом примере покажут лишь мусор.
Технически, суррогатные пары возможно обнаружить по их кодам: если код символа находится в диапазоне , то это — первая часть суррогатной пары. Следующий символ — вторая часть — имеет код в диапазоне . Эти два диапазона выделены исключительно для суррогатных пар по стандарту.
В данном случае:
Дальше в главе Перебираемые объекты будут ещё способы работы с суррогатными парами. Для этого есть и специальные библиотеки, но нет достаточно широко известной, чтобы предложить её здесь.
Во многих языках есть символы, состоящие из некоторого основного символа со знаком сверху или снизу.
Например, буква — это основа для . Наиболее используемые составные символы имеют свой собственный код в таблице UTF-16. Но не все, в силу большого количества комбинаций.
Чтобы поддерживать любые комбинации, UTF-16 позволяет использовать несколько юникодных символов: основной и дальше один или несколько особых символов-знаков.
Например, если после добавить специальный символ «точка сверху» (код ), отобразится Ṡ.
Если надо добавить сверху (или снизу) ещё один знак — без проблем, просто добавляем соответствующий символ.
Например, если добавить символ «точка снизу» (код ), отобразится S с точками сверху и снизу: .
Добавляем два символа:
Это даёт большую гибкость, но из-за того, что порядок дополнительных символов может быть различным, мы получаем проблему сравнения символов: можно представить по-разному символы, которые ничем визуально не отличаются.
Например:
Для решения этой проблемы есть алгоритм «юникодной нормализации», приводящий каждую строку к единому «нормальному» виду.
Его реализует метод str.normalize().
Забавно, но в нашем случае «схлопывает» последовательность из трёх символов в один: — S с двумя точками.
Разумеется, так происходит не всегда. Просто Ṩ — это достаточно часто используемый символ, поэтому создатели UTF-16 включили его в основную таблицу и присвоили ему код.
Подробнее о правилах нормализации и составлении символов можно прочитать в дополнении к стандарту Юникод: Unicode Normalization Forms. Для большинства практических целей информации из этого раздела достаточно.
Комментарии
Со временем программы становятся всё сложнее и сложнее. Возникает необходимость добавлять комментарии, которые бы описывали, что делает код и почему.
Комментарии могут находиться в любом месте скрипта. Они не влияют на его выполнение, поскольку движок просто игнорирует их.
Однострочные комментарии начинаются с двойной косой черты .
Часть строки после считается комментарием. Такой комментарий может как занимать строку целиком, так и находиться после инструкции.
Как здесь:
Многострочные комментарии начинаются косой чертой со звёздочкой и заканчиваются звёздочкой с косой чертой .
Как вот здесь:
Содержимое комментария игнорируется, поэтому, если мы поместим внутри код , он не будет исполняться.
Это бывает удобно для временного отключения участка кода:
Используйте горячие клавиши!
В большинстве редакторов строку кода можно закомментировать, нажав комбинацию клавиш Ctrl+/ для однострочного комментария и что-то, вроде Ctrl+Shift+/ – для многострочных комментариев (выделите кусок кода и нажмите комбинацию клавиш). В системе Mac попробуйте Cmd вместо Ctrl.
Вложенные комментарии не поддерживаются!
Не может быть внутри .
Такой код «умрёт» с ошибкой:
Не стесняйтесь использовать комментарии в своём коде.
Комментарии увеличивают размер кода, но это не проблема. Есть множество инструментов, которые минифицируют код перед публикацией на рабочий сервер. Они убирают комментарии, так что они не содержатся в рабочих скриптах. Таким образом, комментарии никоим образом не вредят рабочему коду.
Позже в учебнике будет глава Качество кода, которая объяснит, как лучше писать комментарии.
Инкремент/декремент
Одной из наиболее частых операций в JavaScript, как и во многих других языках программирования, является увеличение или уменьшение переменной на единицу.
Для этого существуют даже специальные операторы:
-
Инкремент увеличивает на 1:
-
Декремент уменьшает на 1:
Важно:
Инкремент/декремент можно применить только к переменной. Попытка использовать его на значении, типа 5++, приведёт к ошибке.
Операторы и могут быть расположены не только после, но и до переменной.
- Когда оператор идёт после переменной – это «постфиксная форма»: .
- «Префиксная форма» – это когда оператор идёт перед переменной: .
Обе эти формы записи делают одно и то же: увеличивают на .
Есть ли разница между ними? Да, но увидеть её мы сможем, только если будем использовать значение, которое возвращают .
Давайте проясним этот момент. Как мы знаем, все операторы возвращают значение. Операторы инкремент/декремент не исключение. Префиксная форма возвращает новое значение, в то время как постфиксная форма возвращает старое (до увеличения/уменьшения числа).
Чтобы увидеть разницу, вот небольшой пример:
В строке префиксная форма увеличения , она возвращает новое значение . Так что покажет .
Теперь посмотрим на постфиксную форму:
В строке постфиксная форма также увеличивает , но возвращает старое значение (которое было до увеличения). Так что покажет .
Подведём итоги:
-
Если результат оператора не используется, а нужно только увеличить/уменьшить переменную – без разницы, какую форму использовать:
-
Если хочется тут же использовать результат, то нужна префиксная форма:
-
Если нужно увеличить и при этом получить значение переменной до увеличения – постфиксная форма:
Инкремент/декремент можно использовать в любых выражениях
Операторы могут также использоваться внутри выражений. Их приоритет выше, чем у арифметических операций.
Например:
Сравните с:
Хотя технически всё в порядке, такая запись обычно делает код менее читабельным. Одна строка выполняет множество действий – нехорошо.
При беглом чтении кода можно с лёгкостью пропустить такой , и будет неочевидно, что переменная увеличивается.
Лучше использовать стиль «одна строка – одно действие»:
Поиск подстроки
Существует несколько способов поиска подстроки.
Первый метод — str.indexOf(substr, pos).
Он ищет подстроку в строке , начиная с позиции , и возвращает позицию, на которой располагается совпадение, либо при отсутствии совпадений.
Например:
Необязательный второй аргумент позволяет начать поиск с определённой позиции.
Например, первое вхождение — на позиции . Для того, чтобы найти следующее, начнём поиск с позиции :
Чтобы найти все вхождения подстроки, нужно запустить в цикле. Каждый раз, получив очередную позицию, начинаем новый поиск со следующей:
Тот же алгоритм можно записать и короче:
Также есть похожий метод str.lastIndexOf(substr, position), который ищет с конца строки к её началу.
Он используется тогда, когда нужно получить самое последнее вхождение: перед концом строки или начинающееся до (включительно) определённой позиции.
При проверке в условии есть небольшое неудобство. Такое условие не будет работать:
Мы ищем подстроку , и она здесь есть, прямо на позиции . Но не показывается, т. к. возвращает , и решает, что тест не пройден.
Поэтому надо делать проверку на :
Существует старый трюк с использованием — . Он преобразует число в 32-разрядное целое со знаком (signed 32-bit integer). Дробная часть, в случае, если она присутствует, отбрасывается. Затем все биты числа инвертируются.
На практике это означает простую вещь: для 32-разрядных целых чисел значение равно .
В частности:
Таким образом, равняется 0 только при (для любого , входящего в 32-разрядные целые числа со знаком).
Соответственно, прохождение проверки означает, что результат отличен от , совпадение есть.
Это иногда применяют, чтобы сделать проверку компактнее:
Обычно использовать возможности языка каким-либо неочевидным образом не рекомендуется, но этот трюк широко используется в старом коде, поэтому его важно понимать. Просто запомните: означает «если найдено»
Просто запомните: означает «если найдено».
Впрочем, если быть точнее, из-за того, что большие числа обрезаются до 32 битов оператором , существуют другие числа, для которых результат тоже будет , самое маленькое из которых — . Поэтому такая проверка будет правильно работать только для строк меньшей длины.
На данный момент такой трюк можно встретить только в старом коде, потому что в новом он просто не нужен: есть метод (см. ниже).
Более современный метод str.includes(substr, pos) возвращает , если в строке есть подстрока , либо , если нет.
Это — правильный выбор, если нам необходимо проверить, есть ли совпадение, но позиция не нужна:
Необязательный второй аргумент позволяет начать поиск с определённой позиции:
Методы str.startsWith и str.endsWith проверяют, соответственно, начинается ли и заканчивается ли строка определённой строкой:
Разбор худшего в мире куска кода
Перевод
Есть одна итальянская страница на Facebook. Называется она «Il Programmatore di Merda», что в переводе означает «Дерьмовый программист». Мне нравится эта страница.
Там часто публикуют куски отвратительного кода и мемы о программировании. Но однажды я увидел там кое-что совершенно потрясающее.
Этот кусок кода заслужил почётное звание «лучшего произведения» за неделю.
Я решил этот код разобрать, но тут так много всего неправильного, что мне сложно даже выбрать первую проблему для анализа.
Если вы — начинающий программист, то мой материал поможет вам понять то, какие ужасные ошибки совершены тем, кто писал этот код.
Операторы
JavaScript поддерживает следующие операторы:
- Арифметические
-
Простые , а также деление по модулю и возведение в степень .
Бинарный плюс объединяет строки. А если одним из операндов является строка, то второй тоже будет конвертирован в строку:
- Операторы присваивания
-
Простые и составные .
- Битовые операции
-
Битовые операторы работают с 32-битными целыми числами на самом низком, побитовом уровне. Подробнее об их использовании можно прочитать на ресурсе MDN.
- Условный оператор
-
Единственный оператор с тремя параметрами: . Если условие истинно, возвращается , иначе – .
- Логические операторы
-
Логические И , ИЛИ используют так называемое «ленивое вычисление» и возвращают значение, на котором оно остановилось (не обязательно или ). Логическое НЕ конвертирует операнд в логический тип и возвращает инвертированное значение.
- Сравнение
-
Проверка на равенство значений разных типов конвертирует их в число (за исключением и , которые могут равняться только друг другу), так что примеры ниже равны:
Другие операторы сравнения тоже конвертируют значения разных типов в числовой тип.
Оператор строгого равенства не выполняет конвертирования: разные типы для него всегда означают разные значения.
Значения и особенные: они равны только друг другу, но не равны ничему ещё.
Операторы сравнения больше/меньше сравнивают строки посимвольно, остальные типы конвертируются в число.
- Другие операторы
-
Существуют и другие операторы, такие как запятая.
Подробности: Операторы, Операторы сравнения, Логические операторы.
Чего НЕ может JavaScript в браузере?
Возможности JavaScript в браузере ограничены ради безопасности пользователя. Цель заключается в предотвращении доступа недобросовестной веб-страницы к личной информации или нанесения ущерба данным пользователя.
Примеры таких ограничений включают в себя:
-
JavaScript на веб-странице не может читать/записывать произвольные файлы на жёстком диске, копировать их или запускать программы. Он не имеет прямого доступа к системным функциям ОС.
Современные браузеры позволяют ему работать с файлами, но с ограниченным доступом, и предоставляют его, только если пользователь выполняет определённые действия, такие как «перетаскивание» файла в окно браузера или его выбор с помощью тега .
Существуют способы взаимодействия с камерой/микрофоном и другими устройствами, но они требуют явного разрешения пользователя. Таким образом, страница с поддержкой JavaScript не может незаметно включить веб-камеру, наблюдать за происходящим и отправлять информацию в ФСБ.
-
Различные окна/вкладки не знают друг о друге. Иногда одно окно, используя JavaScript, открывает другое окно. Но даже в этом случае JavaScript с одной страницы не имеет доступа к другой, если они пришли с разных сайтов (с другого домена, протокола или порта).
Это называется «Политика одинакового источника» (Same Origin Policy). Чтобы обойти это ограничение, обе страницы должны согласиться с этим и содержать JavaScript-код, который специальным образом обменивается данными.
Это ограничение необходимо, опять же, для безопасности пользователя. Страница , которую открыл пользователь, не должна иметь доступ к другой вкладке браузера с URL и воровать информацию оттуда.
-
JavaScript может легко взаимодействовать с сервером, с которого пришла текущая страница. Но его способность получать данные с других сайтов/доменов ограничена. Хотя это возможно в принципе, для чего требуется явное согласие (выраженное в заголовках HTTP) с удалённой стороной. Опять же, это ограничение безопасности.
Подобные ограничения не действуют, если JavaScript используется вне браузера, например — на сервере. Современные браузеры предоставляют плагины/расширения, с помощью которых можно запрашивать дополнительные разрешения.
Языки «над» JavaScript
Синтаксис JavaScript подходит не под все нужды. Разные люди хотят иметь разные возможности.
Это естественно, потому что проекты разные и требования к ним тоже разные.
Так, в последнее время появилось много новых языков, которые транспилируются (конвертируются) в JavaScript, прежде чем запустятся в браузере.
Современные инструменты делают транспиляцию очень быстрой и прозрачной, фактически позволяя разработчикам писать код на другом языке, автоматически преобразуя его в JavaScript «под капотом».
Примеры таких языков:
- CoffeeScript добавляет «синтаксический сахар» для JavaScript. Он вводит более короткий синтаксис, который позволяет писать чистый и лаконичный код. Обычно такое нравится Ruby-программистам.
- TypeScript концентрируется на добавлении «строгой типизации» для упрощения разработки и поддержки больших и сложных систем. Разработан Microsoft.
- Flow тоже добавляет типизацию, но иначе. Разработан Facebook.
- Dart стоит особняком, потому что имеет собственный движок, работающий вне браузера (например, в мобильных приложениях). Первоначально был предложен Google, как замена JavaScript, но на данный момент необходима его транспиляция для запуска так же, как для вышеперечисленных языков.
Есть и другие. Но даже если мы используем один из этих языков, мы должны знать JavaScript, чтобы действительно понимать, что мы делаем.
JavaScript, Python или Go: что лучше всего подойдёт для бэкенд-разработки в 2021 году?
Перевод
Уже прошло почти восемь месяцев 2020 года, а технические прогнозы на этот год всё выходят и выходят. И это — несмотря на то, что очень сложно предсказать будущее в такой динамично развивающейся индустрии, как разработка программного обеспечения. Тот, кто работает в этой индустрии, видел, как технологии приходят и уходят. Иногда эти технологии проводят свою недолгую жизнь практически незаметно. Технологиям нелегко выживать в мире программирования.
Но если вспомнить прошлое, окажется, что языки программирования имеют огромную историю. В их истории было множество заметных событий, оказавших серьёзное влияние на индустрию. Например, C и Java, одни из самых старых языков программирования, до сих пор находят широкое применение. Но если поинтересоваться их популярностью, окажется, что сейчас они занимают не самые высокие позиции.
Я — программист. Мне очень нравится JavaScript (у меня с этим языком, так сказать, «вечная связь»), я пишу на этом языке уже давно. Но если немного оглядеться, то можно заметить, что в мире разработки ПО есть и другие языки. Предлагаю поразмыслить о том, что лучше использовать для серверной разработки в 2021 году: JavaScript, Python или Go. Но, прежде чем говорить о сильных сторонах каждого из этих языков, давайте взглянем на результаты некоторых исследований.