All JavaScript Flashcards
Какие типы данных есть в JavaScript?
Number
String
Boolean
Null
Undefined
Object
Symbol
Как в JavaScript хранятся числа? Какие ошибки могут возникать при их использовании?
Числа хранятся в 64 битном формате, с плавающей точкой двойной точности.
Ошибки могут возникать при записи дробей. Так как не все дроби удобно представимы в двоичной системе, у них может возникать мантисса (её можно отбрасывать при помощи округления).
Как кодируются строки? Что такое суррогатные пары и как реализуются диакритические знаки?
Используется кодировка UTF-16 – символы кодируются 16-битными словами. Этого хватает для большинства символов, остальные же кодируются двумя словами - такие символы называют суррогатными парами.
Диакритические знаки можно реализовать если добавить коды символов (верхняя точка, нижний апостроф, …) после самого символа.
Чем отличаются null и undefined?
Undefined - это внутренняя переменная языка, которая показывает что мы пытаемся получить несуществующий объект.
Null - это ключевое слово, которым пользователь создаёт объект заглушку, чтобы показать отсутствие требуемого результата выполнения части программы.
Чем отличаются function declaration и function expression?
Function declaration всегда создаёт именованную функцию. Такая функция всплывает - она может быть использована до объявления.
Function expression создаёт анонимную функцию, которая может быть немедленно присвоена в переменную, вызвана или передана в другую функцию. Эти функции создаются только когда исполнение кода доходит до них.
Что будет записано в переменную ‘с’?
let a = 1; let b = 2;
let c = 3 - (a = b + 1);
Так как оператор присваивания возвращает результат присваивания, с=3-(2+1)=0
Чему равен this у функции?
Если функция вызывается из объекта, то this ссылается на этот объект.
Если функция не принадлежит объекту, то this будет undefined в строгом режиме или будет ссылаться на глобальный объект (window в браузере) в обычном режиме.
Также this может быть потерян если мы передадим метод объекта в другую функцию вне объекта. Также this может быть явно указан в методах call и apply.
Как объекты приводятся к примитивам?
Для определения, к какому типу нужно приводить объект, javascript использует хинты ‘string’, ‘number’ и ‘default’.
Сначала вызывается objSymbol.toPrimitive, если он не существует и хинт - строка, то вызывается сначала obj.toString() а затем obj.valueOf(). Если хинт - число или дефолтный, интерпретатор пытается вызвать эти методы в обратном порядке.
Как можно осуществить проверку на undefined?
if( x === undefined) {}
if( typeof x === ‘undefined’ ) {}
Последний метод позволяет избежать ошибки если переменная х не была объявлена. Но на практике это встречается редко.
Деструктурирующее присваивание.
Сработает ли этот код?
let width, height;
{width, height} = {width: 200, height: 200};
Нет, потому что при деструктурирующем присваивании js решит, что он вошёл в блок кода и не увидит объявленных ранее переменных width и height.
Чтобы указать js на то, что мы не в блоке кода, можно использовать скобки:
({width, height} = {width: 200, height: 200});
Как реализуется лексическое окружение у функций, блоков кода и скриптов? Что оно хранит? Как туда записываются переменные?
Лексическое окружение существует в виде объекта Lexical Environment, который состоит из двух частей:
- EnvironmentRecord - хранит в себе переменные, значение this, и другие свойства.
- Ссылка на внешнее лексическое окружение.
Переменные - это просто свойства EnvironmentRecord.
Как функции в JavaScript узнают о внешнем лексическом окружении?
При рождении, каждая функция получает внутреннее свойство [[Environment]], которое ссылается на объект внешнего лексического окружения.
Какова главная особенность лексического окружения в циклах?
Каждую итерацию создаётся новое лексическое окружение.
Сделайте набор «готовых к употреблению» фильтров:
- inBetween(a, b) – между a и b (включительно).
- inArray([…]) – находится в данном массиве.
Они должны использоваться таким образом:
- arr.filter(inBetween(3,6)) – выбирает только значения между 3 и 6 (включительно).
- arr.filter(inArray([1,2,3])) – выбирает только элементы, совпадающие с одним из элементов массива
function inBetween(a, b) { return function(x) { return x >= a && x <= b; }; }
function inArray(arr) { return function(x) { return arr.includes(x); }; }
Какие особенности у ключевого слова var?
- Область видимости var ограничена только функциями.
- Переменные var инициализируются сразу при начале выполнения кода/функции.
- Переменную с var можно объявить несколько раз.
Зачем нужны методы функций call/apply? Чем они отличаются?
Методы нужны чтобы вызвать функцию и явно указать ей контекст выполнения (this).
Метод call принимает аргументы функции через запятую, метод apply принимает массив аргументов.
Из каких полей состоит дескриптор свойства объекта?
Value
Writable
Enumerable
Configurable
Как можно получить доступ к прототипу объекта зная его функцию конструктор F() ?
Прототип будет доступен через свойство F.prototype функции конструктора.
На что по умолчанию ссылается свойство prototype у функций?
Каждая функция по умолчанию через prototype ссылается на объект с одним свойством - constructor - которое ссылается обратно на эту функцию.
Чем промисы лучше или удобнее коллбэков?
- Отсутствует вложенность благодаря использованию цепочек (callback hell)
- Более удобный синтаксис обработки ошибок
- Удобно подписывать сразу несколько потребителей (колбэк может быть только один)
Когда колбэк может быть предпочительнее промиса?
Когда колбэк может быть переиспользован или вызван несколько раз. Промис вызывается единожды.
What is the difference between slice and splice?
Slice
- Doesn’t modify the original array(immutable)
- Returns the subset of original array
Splice
- Modifies the original array(mutable) - removes returned arguments and appends all its argumens starting from third
- Returns the deleted elements as array - splice(1, 3) will return 3 elements starting from 1
How do you compare Object and Map?
Objects have been used as Maps historically. But there are important differences:
- The keys of an Object are Strings and Symbols, whereas they can be any value for a Map, including functions, objects, and any primitive.
- The keys in Map are ordered while keys added to Object are not. Thus, when iterating over it, a Map object returns keys in order of insertion.
- You can get the size of a Map easily with the size property, while the number of properties in an Object must be determined manually.
- A Map is an iterable and can thus be directly iterated, whereas iterating over an Object requires obtaining its keys in some fashion and iterating over them.
- An Object has a prototype, so there are default keys in the map that could collide with your keys if you’re not careful. As of ES5 this can be bypassed by using map = Object.create(null), but this is seldom done.
- A Map may perform better in scenarios involving frequent addition and removal of key pairs.