JavaScript спецификация: темные стороны

3
7254
Добавить в избранное

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

JavaScript спецификация

Мы не будем заострять внимание на востребованности JS. Чтобы понять, о чем пойдет речь, предлагаем ознакомиться со статьями «JavaScript и то, что вы о нем не знали», а также «Перлы языка JavaScript».

Добавление RegExps

Знаете ли вы, что можете добавлять такие цифры?

Объяснение:

Функции вызова

Давайте объявим функцию, которая выводит все параметры в консоль:

Несомненно, вы знаете, что эту функцию можно вызвать следующим образом:

Но знаете ли вы, что можете вызвать любую функцию вот так?

Объяснение:

Это вовсе не волшебство. В приведенном выше примере функция f является тегом для шаблонного литерала. Первый аргумент содержит массив строковых значений. Остальные аргументы связаны с выражениями. Пример:

Это волшебство знаменитой библиотеки под названием styled-components, столь популярной в сообществе React.

Ссылка на спецификацию:

Вызов вызов вызов

Найдено у @cramforce.

Объяснение:

Внимание, это может сломать вам голову! Попробуйте мысленно воспроизвести этот код: мы применяем метод call с помощью метода apply. Узнайте больше:

JavaScript спецификация: свойство конструктора

Объяснение:

Давайте рассмотрим этот пример шаг за шагом:

Object.prototype.constructor возвращает ссылку на функцию-конструктор объекта, которая создала объект экземпляра. В случае со строками  – это строка, в случае с числами – это число и т. д.

Объект как ключ к свойствам объекта

Объяснение:

Почему это так работает? Здесь мы используем вычисленное имя объекта. Когда вы передаете объект между этими скобками, получаете ключ свойства ‘[object Object]’ и значение {}.

Мы можем сделать следующим образом:

Подробнее об объектных читайте здесь:

Доступ к прототипам с помощью __proto__

Порой JavaScript элементы поражают. Как мы знаем, примитивы не имеют прототипов. Но если мы попытаемся получить значение примитивов __proto__, мы получим следующее:

Объяснение:

Это происходит потому, что, когда что-то не имеет прототипа, оно будет завернуто в оболочку с использованием метода ToObject. Итак, шаг за шагом:

Вот более подробная информация о __proto__:

${{Object}}

Каков результат приведенного ниже выражения?

Ответ:

Объяснение:

Мы определили объект со свойством Object, используя Shorthand property notation:

Затем мы передали этот объект в шаблонный литерал, так что метод toString вызывает данный объект. Вот почему мы получаем строку ‘[object Object]’.

Деструктурирование со значениями по умолчанию

Рассмотрим этот пример:

Отличная задача для собеседования. Какое значение y? Ответ:

Объяснение:

В приведенном выше примере:

  1. Мы объявляем x без значения, поэтому он не определен.
  2. Затем мы упаковываем значение x в свойство объекта x.
  3. Затем мы извлекаем значение x, используя деструктурирование, и хотим назначить его y. Если значение не определено, мы будем использовать 1 в качестве значения по умолчанию.
  4. Возвращаем значение y.

Такие JavaScript элементы, как точки и их расширение

Интересные примеры могут быть составлены с расширением массивов. Учтем это:

Объяснение:

Почему 3? Когда мы используем оператор расширения, вызывается метод @@iterator, и возвращаемый итератор используется для получения значений, которые нужно повторить. По умолчанию итератор для строки расширяет строку символами. После расширения мы собираем эти символы в массив. Затем мы снова расширяем данный массив и снова упаковываем его в массив.

Строка ‘…’ состоит из трех точек (символов), поэтому длина результирующего массива равна трем.

Теперь, шаг за шагом:

Очевидно, что мы можем распределять элементы массива столько раз, сколько хотим:

Labels

Не так много программистов знают о метках в JavaScript. Они интересны:

Объяснение:

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

В приведенном выше примере мы идентифицируем метку foo. После этого выполняется console.log (‘first’); , а затем мы прерываем выполнение.

JavaScript элементы «метки»:

Вложенные ярлыки

Объяснение:

Как и в предыдущих примерах, следуйте по этим ссылкам:

Коварный try..catch

Что именно должно вернуться, исходя из приведенного ниже примера? 2 или 3?

Ответ 3. Удивлены?

Объяснение:

Относится ли это к множественному наследованию?

Некоторые JavaScript элементы заставляют серьезно поразмыслить. Взгляните на представленный код:

Является ли это множественным наследованием? Нет.

Объяснение:

Значение extends ((String, Array)) представляет собой любопытную часть кода. Оператор группировки всегда возвращает свой последний аргумент, поэтому (String, Array) – это на самом деле просто Array. Значит, мы создали класс, который просто наследует массив.

Генератор

Рассмотрим пример генератора:

Как вы можете видеть, возвращаемое значение – это объект со значением, равным f. В данном случае мы можем сделать что-то вроде этого:

Объяснение:

Предлагаем к прочтению такие разделы спецификации:

Класс класса

И снова JavaScript элементы ведут себя вне законов логики. Рассмотрим запутанный синтаксис:

Кажется, мы объявляем класс внутри класса. Должны быть и ошибки, однако, мы получаем строку ‘object’.

Объяснение:

Начиная с эпохи ECMAScript 5, ключевые слова допускаются как имена свойств. Поэтому подумайте об этом простом примере:

И ES6 стандартизовал сокращенные определения методов. Кроме того, классы могут быть анонимными. Поэтому, если мы отбросим : function, то получим:

Результат класса по умолчанию всегда является простым объектом. И его typeof должно возвращать ‘object’.

Подробнее здесь:

Non-coercible objects

С известными символами есть способ избавиться от принуждения типа JS. Взгляните:

Теперь мы можем использовать это следующим образом:

Запутанные стрелочные функции

Рассмотрим приведенный ниже пример:

Хорошо, хорошо, но что насчет этого?

Объяснение:

Вы можете ожидать {} вместо undefined. Это связано с тем, что фигурные скобки являются частью синтаксиса стрелочных функций, поэтому f вернется undefined.

Трудное возвращение

С return тоже не все так чисто. Учтите данный нюанс:

Объяснение:

Дело в том, что return и возвращаемое выражение должны находиться в одной строке:

Доступ к свойствам объекта с использованием массивов

Такие JavaScript элементы как массивы заслуживают отдельного раздела «необъяснимо, но факт». Тем не менее, затронем мы их здесь:

Как насчет псевдо-многомерных массивов?

Объяснение:

Оператор скобок [] преобразует выражение, переданное toString. Преобразование одноэлементного массива в строку – это такое же преобразование элемента в строку:

Прочие источники

  1. wtfjs.com – коллекция тех самых специфических нарушений, несоответствий и просто мучительно нелогичных моментов.
  2. Wat – молниеносная речь Гэри Бернхардта, CodeMash 2012
  3. What the… JavaScript? – Кайл Симпсонс рассказывает о вытаскивании всего самого странного из JavaScript. Он помогает производить более чистый, элегантный и читаемый код, а затем вдохновляет ЦА присоединиться к Open Source сообществу.
Интересуетесь веб-разработкой?

Подпишитесь на нашу рассылку, чтобы получать больше интересных материалов:

И не беспокойтесь, мы тоже не любим спам. Отписаться можно в любое время.




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