В чем разница между == и ===?
Мне кажется, что операторы == и === работают одинаково. Например:
Оператор == короче и часто встречается в других языках программирования. Так зачем === вообще?
![]()
Операторы === и !== являются операторами строгого сравнения. Значит, если операнды имеют разные типы, то не являются равными. Например:
Операторы == и != являются операторами, скажем, грубого сравнения. То есть, если операнды имеют разные типы, JavaScript пытается как-то преобразовать их, чтобы стали сравнимыми. Например:
Интересно заметить, что в отличие от === , оператор == не является транзитивным:
Не очень легко помнить правила этого грубого сравнения, и иногда бывает, что оно работает неожиданным образом. Поэтому, я рекомендую использовать === вместо == .
Даже я не помню мелкие детали оператора == , так что посмотрим в спецификации, пункт 11.9.3:
JavaScript. Собеседование
Для начала давайте поговорим о том, что у них общего.
Во-первых, они принадлежат к 7 «примитивам» (примитивным типам) JS:
Во-вторых, они являются ложными значениями, т.е. результатом их преобразования в логическое значение с помощью Boolean() или оператора «!!» является false:
Ладно, теперь о различиях.
undefined («неопределенный») представляет собой значение по умолчанию:
- переменной, которой не было присвоено значения, т.е. объявленной, но не инициализированной переменной;
- функции, которая ничего не возвращает явно, например, console.log(1);
- несуществующего свойства объекта.
В указанных случаях движок JS присваивает значение undefined.
null — это «значение отсутствия значения». null — это значение, которое присваивается переменной явно. В примере ниже мы получаем null, когда метод fs.readFile отрабатывает без ошибок:
При сравнении null и undefined мы получаем true, когда используем оператор «==», и false при использовании оператора «== brush:html;auto-links:false;toolbar:false» contenteditable=»false»>console.log(null == undefined) // true console.log(null === undefined) // false
Для чего используется оператор «&&»?
Оператор «&&» (логическое и) находит и возвращает первое ложное значение либо последний операнд, когда все значения истинные. Он использует короткое замыкание во избежание лишних затрат:
С оператором «if»:
То же самое с оператором «&&»:
Для чего используется оператор «||»?
Оператор «||» (логическое или) находит и возвращает первое истинное значение. Он также использует короткое замыкание. Данный оператор использовался для присвоения параметров по умолчанию в функциях до того, как параметры по умолчанию были стандартизированы в ES6.
Является ли использование унарного плюса (оператор «+») самым быстрым способом преобразования строки в число?
Согласно MDN, оператор «+» действительно является самым быстрым способом преобразования строки в число, поскольку он не выполняет никаких операций со значением, которое является числом.
Что такое DOM?
DOM или Document Object Model (объектная модель документа) — это прикладной программный интерфейс (API) для работы с HTML и XML документами. Когда браузер первый раз читает («парсит») HTML документ, он формирует большой объект, действительно большой объект, основанный на документе — DOM. DOM представляет собой древовидную структуру (дерево документа). DOM используется для взаимодействия и изменения самой структуры DOM или его отдельных элементов и узлов.
Допустим, у нас есть такой HTML:
DOM этого HTML выглядит так:

В JS DOM представлен объектом Document. Объект Document имеет большое количество методов для работы с элементами, их созданием, модификацией, удалением и т.д.
Что такое распространение события (Event Propagation)?
Когда какое-либо событие происходит в элементе DOM, оно на самом деле происходит не только в нем. Событие «распространяется» от объекта Window до вызвавшего его элемента (event.target). При этом событие последовательно пронизывает (затрагивает) всех предков целевого элемента. Распространение события имеет три стадии или фазы:
- Фаза погружения (захвата, перехвата) — событие возникает в объекте Window и опускается до цели события через всех ее предков.
- Целевая фаза — это когда событие достигает целевого элемента.
- Фаза всплытия — событие поднимается от event.target, последовательно проходит через всех его предков и достигает объекта Window.

Что такое всплытие события?
Когда событие происходит в элементе DOM, оно затрагивает не только этот элемент. Событие «всплывает» (подобно пузырьку воздуха в воде), переходит от элемента, вызвавшего событие (event.target), к его родителю, затем поднимается еще выше, к родителю родителя элемента, пока не достигает объекта Window.
Допустим, у нас есть такая разметка:
У метода addEventListener есть третий необязательный параметр — useCapture. Когда его значение равняется false (по умолчанию), событие начинается с фазы всплытия. Когда его значение равняется true, событие начинается с фазы погружения (для «прослушивателей» событий, прикрепленных к цели события, событие находится в целевой фазе, а не в фазах погружения или всплытия. События в целевой фазе инициируют все прослушиватели на элементе в том порядке, в котором они были зарегистрированы независимо от параметра useCapture). Если мы кликнем по элементу child, в консоль будет выведено: child, parent, grandparent, html, document, window. Вот что такое всплытие события.
Что такое погружение события?
Когда событие происходит в элементе DOM, оно происходит не только в нем. В фазе погружения событие опускается от объекта Window до цели события через всех его предков.
У метода addEventListener есть третий необязательный параметр — useCapture. Когда его значение равняется false (по умолчанию), событие начинается с фазы всплытия. Когда его значение равняется true, событие начинается с фазы погружения. Если мы кликнем по элементу child, то увидим в консоли следующее: window, document, html, grandparent, parent, child. Это и есть погружение события.
В чем разница между методами event.preventDefault() и event.stopPropagation()?
Метод event.preventDefault() отключает поведение элемента по умолчанию. Если использовать этот метод в элементе form, то он предотвратит отправку формы (submit). Если использовать его в contextmenu, то контекстное меню будет отключено (данный метод часто используется в keydown для переопределения клавиатуры, например, при создании музыкального/видео плеера или текстового редактора). Метод event.stopPropagation() отключает распространение события (его всплытие или погружение).
Как узнать об использовании метода event.preventDefault()?
Для этого мы можем использовать свойство event.defaulPrevented, возвращающее логическое значение, служащее индикатором применения к элементу метода event.preventDefault.
Почему obj.someprop.x приводит к ошибке?
Ответ очевиден: мы пытаемся получить доступ к свойству x свойства someprop, которое имеет значение undefined. obj.__proto__.__proto = null, поэтому возвращается undefined, а у undefined нет свойства x.
Что такое цель события или целевой элемент (event.target)?
Простыми словами, event.target — это элемент, в котором происходит событие, или элемент, вызвавший событие.
Имеем такую разметку:
И такой простенький JS:
Мы прикрепили «слушатель» к внешнему div. Однако если мы нажмем на кнопку, то получим в консоли разметку этой кнопки. Это позволяет сделать вывод, что элементом, вызвавшим событие, является именно кнопка, а не внешний или внутренние div.
Что такое текущая цель события (event.currentTarget)?
Event.currentTarget — это элемент, к которому прикреплен прослушиватель событий.
И немного видоизмененный JS:
Мы прикрепили слушатель к внешнему div. Куда бы мы ни кликнули, будь то кнопка или один из внутренних div, в консоли мы всегда получим разметку внешнего div. Это позволяет заключить, что event.currentTarget — это элемент, к которому прикреплен прослушиватель событий.
В чем разница между операторами «==» и «== ==» (абстрактное или нестрогое равенство) и оператором «== ==» производит так называемое неявное сравнение. Оператор «= == примитиву» метод toPrimitive сначала использует метод valueOf, затем метод toString.

Все примеры возвращают true.
Первый пример — первое условие алгоритма.
Второй пример — четвертое условие.
Третий — второе.
Четвертый — седьмое.
Пятый — восьмое.
И последний — десятое.

Если же мы используем оператор «== brush:html;auto-links:false;toolbar:false» contenteditable=»false»>let a = < a: 1 >let b = < a: 1 >let c = a console.log(a === b) // false console.log(a === c) // true
В JS объекты и примитивы сравниваются по-разному. Примитивы сравниваются по значению. Объекты — по ссылке или адресу в памяти, где хранится переменная. Вот почему первый console.log возвращает false, а второй — true. Переменные «a» и «c» ссылаются на один объект, а переменные «a» и «b» — на разные объекты с одинаковыми свойствами и значениями.
Для чего используется оператор «!!»?
Оператор «!!» (двойное отрицание) приводит значение справа от него к логическому значению.
Как записать несколько выражений в одну строку?
Для этого мы можем использовать оператор «,» (запятая). Этот оператор «двигается» слева направо и возвращает значение последнего выражения или операнда.
Если мы выведем значение x в консоль, то получим 27. Сначала мы увеличиваем значение x на единицу (x = 6). Затем вызываем функцию addFive() с параметром 6, к которому прибавляем 5 (x = 11). После этого мы умножаем значение x на 2 (x = 22). Затем вычитаем 5 (x = 17). И, наконец, прибавляем 10 (x = 27).
Что такое поднятие (Hoisting)?
Поднятие — это термин, описывающий подъем переменной или функции в глобальную или функциональную области видимости.
Для того, чтобы понять, что такое Hoisting, необходимо разобраться с тем, что представляет собой контекст выполнения.
Контекст выполнения — это среда, в которой выполняется код. Контекст выполнения имеет две фазы — компиляция и собственно выполнение.
Компиляция. В этой фазе функциональные выражения и переменные, объявленные с помощью ключевого слова «var», со значением undefined поднимаются в самый верх глобальной (или функциональной) области видимости (Как бы перемещаются в начало нашего кода. Это объясняет, почему мы можем вызывать функции до их объявления).
Выполнение. В этой фазе переменным присваиваются значения, а функции (или методы объектов) вызываются или выполняются.
Запомните: поднимаются только функциональные выражения и переменные, объявленные с помощью ключевого слова «var». Обычные функции и стрелочные функции, а также переменные, объявленные с помощью ключевых слов «let» и «const» не поднимаются.
Предположим, что у нас есть такой код:
Получаем undefined, 1 и ‘Hello Mark!’.
Вот как выглядит фаза компиляции:
После завершения фазы компиляции начинается фаза выполнения, когда переменным присваиваются значения и вызываются функции.
Что такое область видимости (Scope)?
Область видимости — это место, где (или откуда) мы имеем доступ к переменным или функциям. JS имеет три типа областей видимости: глобальная, функциональная и блочная (ES6).
Глобальная область видимости — переменные и функции, объявленные в глобальном пространстве имен, имеют глобальную область видимости и доступны из любого места в коде.
Функциональная область видимости (область видимости функции) — переменные, функции и параметры, объявленные внутри функции, доступны только внутри этой функции.
Блочная область видимости — переменные (объявленные с помощью ключевых слов «let» и «const») внутри блока (< >), доступны только внутри него.
Область видимости — это также набор правил, по которым осуществляется поиск переменной. Если переменной не существует в текущей области видимости, ее поиск производится выше, во внешней по отношению к текущей области видимости. Если и во внешней области видимости переменная отсутствует, ее поиск продолжается вплоть до глобальной области видимости. Если в глобальной области видимости переменная обнаружена, поиск прекращается, если нет — выбрасывается исключение. Поиск осуществляется по ближайшим к текущей областям видимости и останавливается с нахождением переменной. Это называется цепочкой областей видимости (Scope Chain).

Что такое замыкание (Closures)?
По сути, замыкание — это способность функции во время создания запоминать ссылки на переменные и параметры, находящиеся в текущей области видимости, в области видимости родительской функции, в области видимости родителя родительской функции и так до глобальной области видимости с помощью цепочки областей видимости. Обычно область видимости определяется при создании функции.
Примеры — отличный способ объяснить замыкание:
В данном примере, когда мы объявляем функцию, глобальная область видимости является частью замыкания.

Переменная «globalVar» не имеет значения на картинке, потому что ее значение может меняться в зависимости от того, где и когда будет вызвана функция. Но в примере выше globalVar будет иметь значение «abc».
Теперь пример посложнее:

В результате получаем «guess outer inner». Объяснение следующее: когда мы вызываем функцию outerFunc и присваиваем переменной «x» значение, возвращаемое функцией innerFunc, параметр «outerParam» равняется «outer». Несмотря на то, что мы присвоили переменной «outerVar» значение «outer-2», это произошло после вызова функции outerFunc, которая «успела» найти значение переменной «outerVar» в цепочке областей видимости, этим значением было «outer». Когда мы вызываем «x», которая ссылается на innerFunc, значением «innerParam» является «inner», потому что мы передаем это значение в качестве параметра при вызове «x». globalVar имеет значение «guess», потому что мы присвоили ей это значение перед вызовом «x».
Пример неправильного понимания замыкания.
Данный код работает не так, как ожидается. Объявление переменной с помощью ключевого слова «var» делает эту переменную глобальной. После добавления функций в массив «arrFunc» значением глобальной переменной «i» становится «5». Поэтому когда мы вызываем функцию, она возвращает значение глобальной переменной «i». Замыкание хранит ссылку на переменную, а не на ее значение во время создания. Эту проблему можно решить, используя IIFE или объявив переменную с помощью ключевого слова «let».
Какие значения в JS являются ложными?
Ложными являются значения, результатом преобразования которых в логическое значение является false.
Как проверить, является ли значение ложным?
Следует использовать функцию Boolean или оператор «!!» (двойное отрицание).
Для чего используется директива «use strict»?
«use strict» — это директива ES5, которая заставляет весь наш код или код отдельной функции выполняться в строгом режиме. Строгий режим вводит некоторые ограничения по написанию кода, тем самым позволяя избегать ошибок на ранних этапах.
Вот какие ограничения накладывает строгий режим.
Нельзя присваивать значения или обращаться к необъявленным переменным:
Запрещено присваивать значения глобальным переменным, доступным только для чтения или записи:
Нельзя удалить «неудаляемое» свойство объекта:
Запрещено дублирование параметров:
Нельзя создавать функции с помощью функции eval:
Значением «this» по умолчанию является undefined:
Какое значение имеет this?
Обычно this ссылается на значение объекта, который в данный момент выполняет или вызывает функцию. «В данный момент» означает, что значение this меняется в зависимости от контекста выполнения, от того места, где мы используем this.
В данном случае метод getName возвращает this.name, а this ссылается на carDetails, объект, в котором выполняется getName, который является ее «владельцем».
Добавим после console.log три строчки:
Второй console.log выдает Ford Ranger, и это странно. Причина такого поведения заключается в том, что «владельцем» getCarName является объект window. Переменные, объявленные с помощью ключевого слова «var» в глобальной области видимости, записываются в свойства объекта window. this в глобальной области видимости ссылается на объект window (если речь не идет о строгом режиме).
В этом примере this и window ссылаются на один объект.
Одним из способов решения данной проблемы является использование методов call или apply:
Call и apply принимают в качестве первого аргумента объект, который будет являться значением this внутри функции.
В IIFE, функциях, которые создаются в глобальном области видимости, анонимных функциях и внутренних функциях методов объекта значением this по умолчанию является объект window.
Существует два способа получить «Marko Polo».
Во-первых, мы можем сохранить значение this в переменной:
Во-вторых, мы можем использовать стрелочную функцию:
Стрелочные функции не имеют собственного значения this. Они копируют значение this из внешнего лексического окружения.
Что такое прототип объекта?
В двух словах, прототип — это план (схема или проект) объекта. Он используется как запасной вариант для свойств и методов, существующих в данном объекте. Это также один из способов обмена свойствами и функциональностью между объектами. Это основная концепция прототипного наследования в JS.
Несмотря на то, что объект «о» не имеет свойства toString, обращение к этому свойству не вызывает ошибки. Если определенного свойства нет в объекте, его поиск осуществляется сначала в прототипе объекта, затем в прототипе прототипа объекта и так до тех пор, пока свойство не будет найдено. Это называется цепочкой прототипов. На вершине цепочки прототипов находится Object.prototype.
Что такое IIFE?
IIFE или Immediately Invoked Function Expression — это функция, которая вызывается или выполняется сразу же после создания или объявления. Для создания IIFE необходимо обернуть функцию в круглые скобки (оператор группировки), превратив ее в выражение, и затем вызвать ее с помощью еще одних круглых скобок. Это выглядит так: (function()<>)().
Все эти примеры являются валидными. Предпоследний пример показывает, что мы можем передавать параметры в IIFE. Последний пример показывает, что мы можем сохранить результат IIFE в переменной.
Лучшее использование IIFE — это выполнение функций настройки инициализации и предотвращение конфликтов имен с другими переменными в глобальной области видимости (загрязнение глобального пространства имен). Приведем пример.
У нас есть ссылка на библиотеку somelibrary.js, которая предоставляет некоторые глобальные функции, которые мы можем использовать в нашем коде, но в этой библиотеке есть два метода, createGraph и drawGraph, которые мы не используем, потому что они содержат ошибки. И мы хотим реализовать эти функции самостоятельно.
Одним из способов решить данную проблему является изменение структуры наших скриптов:
Таким образом, мы переопределяем методы, предоставляемые библиотекой.
Вторым способом является изменение имен наших функций:
Третий способ — использование IIFE:
В этом примере мы создаем служебную переменную, которая содержит результат IIFE, возвращающий объект, содержащий методы createGraph и drawGraph.
Вот еще одна проблема, которую можно решить с помощью IIFE:
Допустим, у нас есть элемент «ul» с классом «list-group», содержащий 5 дочерних элементов «li». И мы хотим выводить в консоль значение «i» при клике по отдельному «li». Однако вместо этого в консоль всегда выводится 5. Виной всему замыкание.
Одним из решений является IIFE:
Причина, по которой этот код работает, как задумано, состоит в том, что IIFE создает новую область видимости на каждой итерации, и мы записываем значение «i» в currentIndex.
Для чего используется метод Function.prototype.apply?
Apply используется для привязки определенного объекта к значению this вызываемой функции.
Этот метод похож на Function.prototype.call. Единственное отличие состоит в том, что в apply аргументы передаются в виде массива.
Для чего используется метод Function.prototype.call?
Call используется для привязки определенного объекта к значению this вызываемой функции.
Этот метод похож на Function.prototype.apply. Отличие состоит в том, что в call аргументы передаются через запятую.
В чем разница между методами call и apply?
Отличие между call и apply состоит в том, как мы передаем аргументы в вызываемой функции. В apply аргументы передаются в виде массива, в call — через запятую.
Для чего используется метод Function.prototype.bind?
Bind возвращает новую функцию, значением this которой является объект, указанный в качестве первого параметра. В отличие от bind, call и apply сразу же вызывают функцию.
Что такое функциональное программирование и какие особенности JS позволяют говорить о нем как о функциональном языке программирования?
Функциональное программирование — это декларативная концепция программирования или образец (паттерн) того, как строятся приложения, как используются функции, содержащие выражения, которые вычисляют значения без изменения аргументов, которые им передаются.
Объект Array содержит методы map, filter и reduce, которые являются самыми известными функциями в мире функционального программирования из-за их полезности, а также потому, что они не изменяют массив, что делает эти функции «чистыми». Также в JS имеются замыкание и функции высшего порядка, которые являются характеристиками функционального языка программирования.
Метод map возвращает новый массив с результатами вызова callback для каждого элемента массива:
Метод filter создает новый массив со всеми элементами, которые удовлетворяют условию, указанному в callback:
Метод reduce выполняет callback один раз для каждого элемента массива, за исключением пустот, принимая четыре аргумента: начальное значение (или значение от предыдущего callback), значение текущего элемента, текущий индекс и итерируемый массив:
Что такое функции высшего порядка (Higher Order Functions)?
Функция высшего порядка — это функция, возвращающая другую функцию или принимающая другую функцию в качестве аргумента.
Почему функции в JS называют объектами первого класса (First-class Objects)?
Функции называют объектами первого класса, потому что они обрабатываются также, как и любое другое значение в JS. Они могут присваиваться переменным, быть свойством объекта (методом), элементом массива, аргументом другой функции, значением, возвращаемым функцией. Единственным отличием функции от любого другого значения в JS является то, что функция может быть выполнена или вызвана.
Как бы вы реализовали метод Array.prototype.map?
Метод map создает новый массив с результатом вызова указанной функции для каждого элемента массива.
Как бы вы реализовали метод Array.prototype.filter?
Метод filter создает новый массив со всеми элементами, прошедшими проверку, задаваемую в передаваемой функции.
Как бы вы реализовали метод Array.prototype.reduce?
Метод reduce применяет функцию reducer к каждому элементу массива (слева-направо), возвращая одно результирующее значение.
Что такое объект arguments?
Arguments — это коллекция аргументов, передаваемых функции. Это объект, подобный массиву, у него есть свойство length, мы можем получить доступ к определенному значению с помощью arguments[i], но у него отсутствуют методы forEach, reduce, filter и map. Он позволяет узнать количество параметров функции.
Преобразовать arguments в массив можно с помощью Array.prototype.slice:
Запомните: в стрелочных функциях объект arguments не работает.
Вызов функции four приводит к ошибке ReferenceError: arguments is not defined. Эту проблему можно решить с помощью оператора rest:
Это автоматически поместит все параметры в массив.
Как создать объект, не имеющий прототипа?
Это можно сделать с помощью Object.create:
Почему в представленном коде переменная b становится глобальной при вызове функции?
Так происходит, потому что оператор присваивания (» brush:html;auto-links:false;toolbar:false» contenteditable=»false»>function myFunc() < let a = (b = 0) >myFunc()
Сначала значение 0 присваивается переменной «b», которая не объявлена. Движок JS делает ее глобальной. Возвращаемое выражением b = 0 значение (0) затем присваивается локальной переменной «a».
Эту проблему можно решить сначала объявив локальные переменные, а затем присвоив им значения:
Что такое ECMAScript?
ECMAScript — это спецификация, стандарт скриптовых языков программирования, он является основой JS, поэтому любые изменения ECMAScript отражаются на JS.
Что нового привнес в JS стандарт ES6 или ECMAScript2015?
- Стрелочные функции (Arrow Functions).
- Классы (Classes).
- Шаблонные строки (Template Strings).
- Расширенные объектные литералы (Enhanced Object literals).
- Деструктуризация (Object Destructuring).
- Промисы (Promises).
- Генераторы (Generators).
- Модули (Modules).
- Symbol.
- Прокси (Proxies).
- Множества (Sets).
- Параметры по умолчанию.
- Операторы rest и spread.
- Блочная область видимости (ключевые слова «let» и «const»).
В чем разница между ключевыми словами «var», «let» и «const»?
Переменные, объявленные с помощью ключевого слова «var», являются глобальными. Это означает, что они доступны из любого места в коде:
Результатом первого console.log будет undefined, второго — 5. Мы имеем доступ к переменной «x» из-за ее всплытия в глобальную область видимости. Код из примера выше интерпретируется следующим образом:
Результатом первого console.log является undefined, поскольку объявленные переменные, которым не присвоено значения, имеют значение undefined по умолчанию.
Переменные, объявленные с помощью ключевых слов «let» и «const» имеют блочную область видимости. Это означает, что они доступны только внутри блока (< >):
Вызов этих функций с параметром false приведет к ошибке ReferenceError, потому что к переменным «x» и «y» нет доступа снаружи блока и их значения не возвращаются (не всплывают).
Разница между «let» и «const» состоит в том, что в первом случае мы можем менять значение переменной, а во втором — нет (константа). При этом, мы можем менять значение свойства объекта, объявленного с помощью const, но не само свойство (переменную).
Что такое стрелочные функции (Arrow Functions)?
Стрелочная функция — это относительно новый способ создания функций в JS. Стрелочные функции создаются быстрее и имеют более читаемый синтаксис, чем функциональные выражения. В стрелочных функциях опускается слово «function»:
В функциональном выражении мы используем ключевое слово «return» для возврата значения. В стрелочной функции мы этого не делаем, поскольку стрелочные функции неявно возвращают значения при условии, что мы возвращаем одно выражение или значение:
Мы также можем передавать параметры стрелочным функциям. Если мы передаем один параметр, его можно не оборачивать в круглые скобки:
У стрелочных функций нет доступа к объекту arguments. Поэтому вызов первой функции приведет к ошибке. Для получения параметров, переданных функции, мы можем использовать оператор rest.
Что такое классы (Classes)?
Классы — это относительно новый способ написания функций-конструкторов в JS. Это синтаксический сахар для функций-конструкторов. В основе классов лежат те же прототипы и прототипное наследование:
Переопределение методов и наследование от другого класса:
Как узнать об использовании прототипов?
Что такое шаблонные литералы (Template Literals)?
Шаблонные литералы — относительно новый способ создания строк в JS. Шаблонные литералы создаются с помощью двойных обратных кавычек («):
В шаблонных литералах нам не нужно экранировать одинарные кавычки.
В ES6 нам не нужно использовать управляющую последовательность «\n» для перевода строки.
В ES6 нам не нужно использовать конкатенацию строк для объединения текста с переменной: мы можем использовать выражение $
Что такое деструктуризация объекта (Object Destructuring)?
Деструктуризация — относительно новый способ получения (извлечения) значений объекта или массива.
Допустим, у нас есть такой объект:
Раньше для получения свойств объекта мы создавали переменные для каждого свойства. Это было очень скучно и сильно раздражало:
Использование деструктуризации позволяет сделать код чище и отнимает меньше времени. Синтаксис деструктуризации следующий: заключаем свойства объекта, которые хотим получить, в фигурные скобки (< >), а если речь идет о массиве — в квадратные скобки ([ ]):
Для изменения имени переменной следует использовать «propertyName: newName»:
Для присвоения переменным значения по умолчанию следует использовать «propertyName = ‘defaultValue'»:
Что такое модули (Modules)?
Модули позволяют объединять (использовать) код из разных файлов и избавляют нас от необходимости держать весь код в одном большом файле. До появления модулей в JS существовало две популярные системы модулей для поддержки кода:
- CommonJS — Nodejs
- AMD (AsyncronousModuleDefinition) — Browsers
Синтаксис модулей очень простой: мы используем import для импорта функциональности или значений из другого файла или файлов и export для экспорта.
Экспорт функциональности в другой файл (именной экспорт):
Импорт функциональности в другой файл:
Экспорт по умолчанию:
Что такое объект Set?
Объект Set позволяет хранить уникальные значения, примитивы и ссылки на объекты. Еще раз: в Set можно добавлять только уникальные значения. Он проверяет хранящиеся в нем значения с помощью алгоритма SameZeroValue.
Экземпляр Set создается с помощью конструктора Set. Мы также можем передать ему некоторые значения при создании:
Мы можем добавлять значения в Set, используя метод add. Поскольку метод add является возвращаемым, мы можем использовать цепочку вызовов:
Мы можем удалять значения из Set, используя метод delete:
Мы можем проверить наличие свойства в Set, используя метод has:
Для получения длины Set используется метод size:
Метод clear очищает Set:
Мы можем использовать Set для удаления повторяющихся значений в массиве:
Что такое функция обратного вызова (Callback Function)?
Функция обратного вызова — это функция, вызов которой отложен на будущее (происходит при некоторых условиях, например, при наступлении события).
В примере мы ждем события «клик» на элементе с идентификатором «btnAdd». По клику вызывается функция clickCallback. Функция обратного вызова добавляет некоторый функционал данным или событию. Методам reduce, filter и map в качестве второго аргумента передается функция обратного вызова. Хорошей аналогией callback является следующая ситуация: Вы звоните кому-то, он не отвечает, Вы оставляете ему сообщение и ждете, когда он перезвонит. Звонок или сообщение — это событие или данные, а callback — это ожидание (предвосхищение) встречного звонка.
Что такое промисы (Promises)?
Промисы — это один из приемов работы с асинхронным кодом в JS. Они возвращают результат асинхронной операции. Промисы были придуманы для решения проблемы так называемого «ада функций обратного вызова».
Проблемы при таком подходе начинаются, когда нам необходимо добавить еще одну асинхронную операцию в первую (внутрь первой), затем еще одну и т.д. В результате мы получаем беспорядочный и нечитаемый код:
А вот как это выглядит с промисами:
У промиса есть четыре состояния:
- Ожидание — начальное состояние промиса. Результата промиса неизвестен, поскольку операция не завершена.
- Выполнено — асинхронная операция выполнена, имеется результат.
- Отклонено — асинхронная операция не выполнена, имеется причина.
- Завершено — выполнено или отклонено.
В качестве параметров конструктор промиса принимает resolve и reject. В resolve записывается результат выполнения операции, в reject — причина невыполнения операции. Результат может быть обработан в методе .then, ошибка — в методе .catch. Метод .then также возвращает промис, поэтому мы можем использовать цепочку, состоящую из нескольких .then.
Мы можем создать вспомогательную функцию для преобразования асинхронной операции с callback в промис. Она будет работать наподобие util из Node.js («промисификация»):
Что такое async/await?
Async/await — относительно новый способ написания асинхронного (неблокирующего) кода в JS. Им оборачивают промис. Он делает код более читаемым и чистым, чем промисы и функции обратного вызова. Однако для использования async/await необходимо хорошо знать промисы.
Запомните: использование ключевого слова «async» перед функцией заставляет ее возвращать промис:
Ключевое слово «await» можно использовать только внутри асинхронной функции. Использование «await» внутри другой функции приведет к ошибке. Await ожидает завершения выражения справа, чтобы вернуть его значение перед выполнением следующей строчки кода.
В чем разница между spread-оператором и rest-оператором?
Операторы spread и rest имеют одинаковый синтаксис («. «). Разница состоит в том, что с помощью spread мы передаем или распространяем данные массива на другие данные, а с помощью rest — получаем все параметры функции и помещаем их в массив (или извлекаем часть параметров).
В этом примере мы используем spread при вызове функции add с данными массива nums. Значением переменной «a» будет 5, b = 6, sum = 11.
Здесь мы вызываем функцию add с любым количеством аргументов. Add возвращает сумму этих аргументов.
В этом примере мы используем rest для помещения любого количества параметров, кроме первого, в массив others.
Что такое параметры по умолчанию (Default Parameters)?
Это относительно новый способ определения значений переменных по умолчанию.
Можно использовать деструктуризацию:
Мы даже можем использовать по умолчанию параметры, объявленные в том же месте:
Что такое объектная обертка (Wrapper Objects)?
Примитивы строка, число и boolean имеют свойства и методы, несмотря на то, что они не являются объектами:
Name — это строка (примитивный тип), у которого нет свойств и методов, но когда мы вызываем метод toUpperCase(), это приводит не к ошибке, а к «MARKO».
Причина такого поведения заключается в том, что name временно преобразуется в объект. У каждого примитива, кроме null и undefined, есть объект-обертка. Такими объектами являются String, Number, Boolean, Symbol и BigInt. В нашем случае код принимает следующий вид:
Временный объект отбрасывается по завершении работы со свойством или методом.
В чем разница между явным и неявным преобразованием или приведением к типу (Implicit and Explicit Coercion)?
Неявное преобразование — это способ приведения значения к другому типу без нашего ведома (участия).
Предположим, у нас есть следующее:
Результатом первого console.log будет 16. В других языках это привело бы к ошибке, но в JS 1 конвертируется в строку и конкатенируется (присоединяется) c 6. Мы ничего не делали, преобразование произошло автоматически.
Результатом второго console.log будет 1. False было преобразовано в 0, true — в 1. 0 + 1 = 1.
Результатом третьего console.log будет 12. Строка 2 была преобразована в число перед умножением на 6.
Явное преобразование предполагает наше участие в приведении значения к другому типу:
В этом примере мы используем parseInt для приведения строки 6 к числу, затем складываем два числа и получаем 7.
Что такое NaN? Как проверить, является ли значение NaN?
NaN или Not A Number (не число) — это значение, получаемое в результате выполнения числовой операции над нечисловым значением:
В JS есть встроенный метод isNaN, позволяющий проверять, является ли значение NaN, но он ведет себя довольно странно:
Результатом всех console.log является true, несмотря на то, что ни одно из значений не является NaN.
ES6 для проверки, является ли значение NaN, рекомендует использовать метод Number.isNaN. Мы также можем написать вспомогательную функцию для решения проблемы «неравенства NaN самому себе»:
Как проверить, является ли значение массивом?
Для этого следует использовать метод Array.isArray:
Если среда, в которой вы работаете, не поддерживает данный метод, можете использовать такой полифил:
Как определить наличие свойства в объекте?
Существует три способа это сделать.
Первый способ состоит в использовании оператора «in»:
Второй — использовать метод hasOwnProperty:
Третий — индексная нотация массива:
Что такое AJAX?
AJAX или Asyncronous JavaScript and XML — это набор взаимосвязанных технологий, которые позволяют работать с данными в асинхронном режиме. Это означает, что мы можем отправлять данные на сервер и получать данные с него без перезагрузки веб-страницы.
AJAX использует следующие технологии:
- HTML — структура веб-страницы.
- CSS — стили веб-страницы.
- JavaScript — поведение страницы и работа с DOM.
- XMLHttpRequest API — отправка и получение данных с сервера.
- PHP, Python, Nodejs — какой-нибудь серверный язык.
Как в JS создать объект?
В чем разница между методами Object.freeze и Object.seal?
Разница заключается в том, что при использовании метода Object.freeze мы не можем менять или редактировать свойства объекта, а при использовании Object.seal у нас такая возможность имеется.
В чем разница между оператором «in» и методом hasOwnProperty?
Отличие состоит в том, что оператор «in» проверяет наличие свойства не только в самом объекте, но и в его прототипах, а метод hasOwnProperty — только в объекте.
Какие приемы работы с асинхронным кодом в JS Вы знаете?
- Функции обратного вызова (Callbacks).
- Промисы (Promises).
- Async/await.
- Библиотеки вроде async.js, blueprint, q, co.
В чем разница между обычной функцией и функциональным выражением?
Допустим, у нас есть следующее:
Вызов notHoistedFunc приведет к ошибке, а вызов hoistedFunc нет, потому что hoistedFunc «всплывает», поднимается в глобальную область видимости, а notHoistedFunc нет.
Что такое запоминание или мемоизация (Memoization)?
Мемоизация — это прием создания функции, способной запоминать ранее вычисленные результаты или значения. Преимущество мемоизации заключается в том, что мы избегаем повторного выполнения функции с одинаковыми аргументами. Недостатком является то, что мы вынуждены выделять дополнительную память для сохранения результатов.
Как бы вы реализовали вспомогательную функцию запоминания?
Мы реализовали функцию мемоизации с одним аргументом. Сделаем ее «мультиаргументной»:
Почему typeof null возвращает object? Как проверить, является ли значение null?
typeof null == ‘object’ всегда будет возвращать true по историческим причинам. Поступало предложение исправить эту ошибку, изменив typeof null = ‘object’ на typeof null = ‘null’, но оно было отклонено в интересах сохранения обратной совместимости (такое изменение повлекло бы за собой большое количество ошибок).
Для проверки, является ли значение null можно использовать оператор строгого равенства (===):
Для чего используется ключевое слово «new»?
Ключевое слово «new» используется в функциях-конструкторах для создания нового объекта (нового экземпляра класса).
Операторы равенства == и === в JavaScript
Если вы читаете этот блог, вы, вероятно, изучаете JavaScript — и это замечательно. Двойное и тройное равно (== и ===) в JavaScript часто заставляют новичков ломать голову. Но пусть вас это не пугает: когда вы узнаете, как работают эти операторы, вы поймете, что такие особенности делают JS еще красивее.
Что такое == и === в JavaScript?
Операторы == и === используются для сравнения и определения степени равенства или идентичности сравниваемых объектов.
И двойное, и тройное равно возвращают true, если сравниваемые объекты равны, а в противном случае возвращают false. Разница между ними в том, что эти операторы используют разные критерии для определения степени равенства.
Учитывая это, давайте на примерах разберемся, чем == отличается от ===.
Как работает оператор == в JavaScript
Двойное равно (==) часто называют «нестрогим равенством», потому что этот оператор выполняет приведение типов перед сравнением.
Это означает, что если типы данных сравниваемых операндов различны, то JavaScript автоматически преобразует один из операндов в тот же тип, что и другой, чтобы их можно было сравнить.
Давайте разберемся с помощью примера.
Здесь у нас есть две переменные, a и b . Тип переменной a — число, а тип переменной b — строка.
Когда мы сравниваем эти две переменные с помощью двойного равенства, мы получаем на выходе true.
Это происходит потому, что перед сравнением переменная a приводится к строковому типу.
После преобразования значения обеих переменных сравниваются. Если они одинаковы, мы получим true, в противном случае — false. В нашем случае это true.
Важно отметить, что фактическое значение остается неизменным. Оно лишь неявно преобразуется при сравнении.
Правила приведения типов
Рассмотренный пример довольно прост, не так ли? Давайте попробуем еще один, а после разберем правила приведения типов.
Итак, как вы думаете, что получится на выходе? Если ваш ответ был true, то, к сожалению, это неверно. Но если вы догадались, что должно получиться false, то поздравляю.
Если ваш ответ был неправильным, не волнуйтесь, потому что сейчас мы познакомимся с несколькими правилами, которые помогут вам разобраться.
Итак, вот правила для приведения типов в JavaScript:
- Если один из операндов является строкой, то второй операнд будет преобразован в строку.
- Если один из операндов является числом, другой операнд будет преобразован в число.
- Если один из операндов является булевым значением, он будет преобразован в число (true станет 1, а false — 0).
- Если один из операндов является объектом, а другой — примитивным значением, то перед сравнением объект будет преобразован в примитивное значение.
- Если один из операндов равен null или undefined, то, чтобы при сравнении вернулось true, второй тоже должен быть null или undefined. В противном случае возвращается false.
Теперь, ознакомившись с правилом из пункта 3, вы знаете, почему в приведенном выше примере наш ответ был false.
Значение переменной a (true) перед сравнением преобразуется в число. После этого мы сравниваем 1 и «true» — и получаем false, потому что переменные содержат разные значения.
Как работает оператор === в JavaScript
Тройное равно (===), также называемое «строгим равенством», работает аналогично двойному равно. Но есть важное отличие: при использовании === типы операндов не приводятся перед сравнением.
При сравнении переменных сначала проверяется, отличаются ли их типы. Если да, то возвращается false. Если типы совпадают, то проверяется значение. Если значения одинаковы и не являются числами, возвращается true.
Наконец, если оба операнда — числа и не NaN, и у них одинаковое значение, то возвращается true. В противном случае — false.
Давайте разберемся в этом с помощью примера:
Мы взяли тот же пример, что и выше, но при сравнении использовали не двойное, а тройное равенство.
Итак, возможно, вы уже угадали ответ. Да, это false, а почему? Потому что тип переменной a — число, а тип переменной b — строка.
При сравнении тройное равенство сначала проверяет типы операндов, а в данном примере эти типы различаются. Поэтому возвращается false.
Давайте рассмотрим другой пример:
Здесь у нас тоже две переменные, a и b . Тип переменной a — boolean, а тип переменной b — число. Если мы будем их сравнивать с помощью строго равенства, оно вернет false — потому что, опять же, переменные имеют разные типы.
Заключение
Операторы == и === в JavaScript — это операторы сравнения, которые мы используем, чтобы определить, равны или нет два значения.
Оператор == выполняет нестрогое сравнение, при необходимости преобразуя типы, чтобы сделать сравнение возможным.
Оператор === выполняет строгое сравнение, без приведения типов. При использовании тройного равно сравниваются и типы, и значения.
Преобразование типов в JavaScript иногда может приводить к неожиданным результатам, поэтому чаще всего при сравнении рекомендуется использовать оператор строгого равенства ===.
В чем разница между операторами и
В программировании есть ситуации для выполнения математических вычислений. Оператор — это символ для выполнения определенных логических или математических функций над значением или переменной. Значение или переменные, с которыми происходят операции, называются операндами. В языках программирования есть различные операторы. Некоторые из них являются арифметическими операторами, операторами отношения, логическими операторами, поразрядными операторами и операторами присваивания. Арифметические операторы поддерживают математические операции, такие как сложение, вычитание, умножение и т. Д. Операторы отношения полезны для поиска взаимосвязи операндов. Побитовые операторы выполняют операции на битовом уровне. Один из основных побитовых операторов — это побитовое И. Он представлен с помощью &. Логические операторы помогают анализировать несколько условий для принятия решения. Один из основных логических операторов — это логическое И. Он представлен с помощью &&. В этой статье обсуждается разница между & и &&. В ключевое отличие между & и && это то, что & — это побитовый оператор, а && — логический оператор.
1. Обзор и основные отличия
2. Что такое & (побитовое И)
3. Что такое && (логическое И)
4. Сходства между & и &&
5. Параллельное сравнение — & vs && в табличной форме
6. Резюме
Что такое & (побитовое И)?
& — побитовый оператор. Программы написаны программистом. Эти программы понятны людям, но не понятны машине или компьютеру. Следовательно, необходимо преобразовать удобочитаемую программу в машиночитаемый формат. Машина распознает двоичные файлы; нули и единицы. Каждый двоичный файл — это бит. Битовая обработка полезна для увеличения скорости. В побитовых операторах, таких как &, оператор работает с битами и выполняет побитовую операцию.
Если a и b — переменные, а a содержит 0, а b содержит 1, то побитовое И равно 0. Если a имеет значение 1, а B имеет значение 0, то на выходе будет 0. Если a имеет значение 0, а B равно 0. со значением 1, то на выходе будет 0. Если и a, и b содержат 1, то на выходе будет 1. Это 1 означает истину, а 0 означает ложь. Предположим, что x равно 4, а y равно 5. Двоичное число 4 равно 100. Двоичное число 5 равно 101. При побитовой операции побитовое И равно 100. При выполнении операции И двух разных значений будет получено 0. Когда оба значения равны 1, тогда на выходе будет 1.
Согласно приведенной выше программе, переменная x имеет значение 4. Двоичное значение 4 равно 100. Переменная y имеет значение 5. Двоичное значение 5 равно 101. Переменная z имеет результат поразрядного И для x и y. Ответ — 100. Это 4. Следовательно, на выходе программы будет отображаться 4.
Что такое && (логическое И)?
Это логический оператор. Он используется для принятия решения на основе нескольких условий. Символ && представляет собой логическое И. При логическом И, если оба операнда не равны нулю, условие становится истинным. Когда переменная x содержит значение 1, а переменная y содержит значение 0, логическое И (x && y) ложно или 0. Один из примеров && следующий.
Согласно приведенной выше программе метка является переменной. Ему присваивается значение 65. В блоках else if сравнивается отметка. Оператор && используется для обозначения операции И. В else if (mark> = 60 && mark <75) проверяет, находится ли переменная mark между 60 и 75. Если оценка меньше 75 и больше или равна 60, оценка будет «B». . В else if (mark> = 45 && mark <60) компилятор проверит, находится ли оценка между 45 и 60. Если оценка больше или равна 45, а оценка меньше 60, тогда оценка будет 'C '. Эти два оператора включают логическое И (&&).
В чем сходство между & и &&?
- Оба являются операторами программирования.
В чем разница между & и &&?
Резюме — & vs &&
Операторы используются для выполнения математических и логических операций. Операторы выполняют эти операции со значениями или переменными. Они известны как операнды. Некоторые операторы являются арифметическими операторами, операторами присваивания и т. Д. Арифметические операции содержат сложение, умножение и т. Д. Операторы присваивания присваивают значения из правых операндов левому операнду. Есть еще два оператора, называемые поразрядными операторами и логическими операторами. Побитовые операторы выполняют операции битового уровня. Логические операторы принимают решения на основе нескольких условий. В этой статье обсуждалась разница между & и &&. Разница между & и && в том, что & — это побитовый оператор, а && — логический.
Загрузите PDF-файл & vs &&
Вы можете загрузить PDF-версию этой статьи и использовать ее в автономных целях в соответствии с примечанием к цитированию. Пожалуйста, скачайте PDF-версию здесь: Разница между & и &&
Разница между & и && в Java

Оператор в Java — это символ, который может выполнять некоторую желаемую операцию с набором значений. В Java есть разные типы операторов, такие как логические, арифметические, побитовые и другие.
В этом руководстве мы попытаемся изучить и понять разницу между операторами & и && в Java.
Оператор & — это побитовый оператор. Поразрядные операторы в основном используются для работы и управления отдельными битами чисел. Он работает с обеих сторон оператора. Побитовый оператор & — это бинарный оператор, побитно выполняющий операцию И над своими операндами.
Следующий код демонстрирует использование оператора & .
&& — это логический оператор И , работающий с логическими операндами. Как следует из названия, логические операторы могут выполнять логическую операцию и комбинировать два или более условий. Их можно использовать с любым типом данных.
Логический оператор && возвращает истину, если оба условия верны. Он оценивает операнды слева направо. Он преобразует каждый операнд в логическое значение и возвращает исходное значение после работы.
PHP :: Логические операторы
PHP поддерживает следующие стандартные логические операторы: AND и && (логическое И), OR и || (логическое ИЛИ), ! (логическое НЕ) и XOR (исключающее ИЛИ). Все они используются в логических выражениях для определения того или иного хода выполнения программы в зависимости от возвращаемого выражением результата и относятся к бинарным операторам, за исключением оператора ! , который является унарным. При использовании логических операторов их операнды преобразуются к булевому типу данных (смотреть), а результат зависит от приведенных логических значений операндов и вида логического оператора (см. таблицу №1 ).
| Пример | Название | Результат |
|---|---|---|
| $a and $b | Логическое И | TRUE, если оба значения и $a, и $b равны TRUE. |
| $a or $b | Логическое ИЛИ | TRUE, если оба значения равны TRUE или хотя бы одно из значений $a или $b равно TRUE. |
| $a xor $b | Исключающее ИЛИ | TRUE, если одно из значений $a или $b равно TRUE, но не оба сразу. |
| ! $a | Логическое НЕ | TRUE, если значение $a не равно TRUE. |
| $a && $b | Логическое И | TRUE, если оба значения и $a, и $b равны TRUE. |
| $a || $b | Логическое ИЛИ | TRUE, если оба значения равны TRUE или хотя бы одно из значений $a или $b равно TRUE. |
Таблица №1. Логические операторы
Разница между операторами AND и && , а также OR и || заключается в том, что операторы AND , OR и XOR имеют более низкий приоритет, который даже ниже, чем у операторов присваивания (см. таблицу операторов PHP ).
Важно понимать, как интерпретатор обрабатывает логические выражения. Если в выражении с оператором || первый (левый) операнд будет иметь значение true или в выражении с оператором && первый операнд будет иметь значение false , то второй (правый) операнд уже вычисляться не будет. Это связано с тем, что конечный результат в таких случаях уже не изменится (см. таблицу №1 ), а следовательно отпадает и необходимость тратить время на обработку кода второго операнда. Однако при этом нужно быть внимательным и не помещать в правый операнд код, от которого может зависеть правильная работа программы.
В чем разница между == и ===?
Мне кажется, что операторы == и === работают одинаково. Например:
Оператор == короче и часто встречается в других языках программирования. Так зачем === вообще?
![]()
Операторы === и !== являются операторами строгого сравнения. Значит, если операнды имеют разные типы, то не являются равными. Например:
Операторы == и != являются операторами, скажем, грубого сравнения. То есть, если операнды имеют разные типы, JavaScript пытается как-то преобразовать их, чтобы стали сравнимыми. Например:
Интересно заметить, что в отличие от === , оператор == не является транзитивным:
Не очень легко помнить правила этого грубого сравнения, и иногда бывает, что оно работает неожиданным образом. Поэтому, я рекомендую использовать === вместо == .
Даже я не помню мелкие детали оператора == , так что посмотрим в спецификации, пункт 11.9.3: