Вопросы, задаваемые на собеседовании на позицию фронтенд разработчика javascript.

Вопросы, задаваемые на собеседовании на позицию фронтенд разработчика javascript.

В чем разница между null и undefined?

null - присваивается явно

undefined - результат не присвоения переменной (обьявлено но не инициализировано), когда ф-ция ничего не возвращает явно (console.log(1)), когда свойство объекта не существует.

Операторы && и ||

“&&” - (логическое и) находит и возвращает первое ложное значение либо последний операнд, когда все значения истинные.

console.log(false && 1 && []) // false
console.log(' ' && true && 5) // 5

”||” - (логическое или) находит и возвращает первое истинное значение.

Является ли использование унарного плюса (оператор “+”) самым быстрым способом преобразования строки в число?

Да т.к. он не выполняет никаких операций со значением, которое является числом.

Что такое распространение события (Event Propagation)?

Когда происходит событие, оно распространяется от Window до вызвавшего элемента, при этом затрагивая всех предков элемента.

Распространение имеет 3 фазы.

Фаза погружения (захвата, перехвата) — от Windows до целевого.

Целевая фаза — это когда событие достигает целевого элемента.

Фаза всплытия — от целевого до Window.

У метода addEventListener есть третий необязательный параметр — useCapture. Когда его значение равняется false (по умолчанию), событие начинается с фазы всплытия. Когда его значение равняется true, событие начинается с фазы погружения.

В чем разница между методами event.preventDefault() и event.stopPropagation()?

Метод event.preventDefault() отключает поведение элемента по умолчанию. Если использовать этот метод в элементе form, то он предотвратит отправку формы (submit).

Метод event.stopPropagation() отключает распространение события (его всплытие или погружение).

Как узнать об использовании метода event.preventDefault()?

Для этого мы можем использовать свойство event.defaulPrevented, возвращающее логическое значение, служащее индикатором применения к элементу метода event.preventDefault.

Что такое цель события или целевой элемент (event.target)?

Простыми словами, event.target — это элемент, в котором происходит событие, или элемент, вызвавший событие.

Что такое текущая цель события (event.currentTarget)?

Event.currentTarget — это элемент, к которому прикреплен прослушиватель событий. На тот случай если мы кликаем на кнопке внутри дива к которому прикрепили событие.

В чем разница между операторами “==” и “===”?

Первый сравнивает значения после их преобразования или приведения (не строгое равенство)

Почему результатом сравнения двух похожих объектов является false?

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

Для чего используется оператор “!!”?

Оператор “!!” (двойное отрицание) приводит значение справа от него к логическому значению.

console.log(!![].length) // false

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

Для этого мы можем использовать оператор “,” (запятая). Этот оператор «двигается» слева направо и возвращает значение последнего выражения или операнда.

let x = 5

x = (x++, x = addFive(x), x *= 2, x -= 5, x += 10)

Что такое поднятие (Hoisting)?

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

Контекст выполнения имеет две фазы — компиляция и собственно выполнение.

Компиляция. В этой фазе функциональные выражения и переменные, объявленные с помощью ключевого слова «var», со значением undefined поднимаются в самый верх глобальной (или функциональной) области видимости (как бы перемещаются в начало нашего кода. Это объясняет, почему мы можем вызывать функции до их объявления — прим. пер.).

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

Поднимаются только функциональные выражения и переменные, объявленные с помощью ключевого слова «var»

Что такое область видимости (Scope)?

Область видимости — это место, где (или откуда) мы имеем доступ к переменным или функциям. JS имеем три типа областей видимости: глобальная, функциональная и блочная (ES6).

Глобальная область видимости — переменные и функции, объявленные в глобальном пространстве имен, имеют глобальную область видимости и доступны из любого места в коде.

Функциональная область видимости (область видимости функции) — переменные, функции и параметры, объявленные внутри функции, доступны только внутри этой функции.

Блочная область видимости — переменные (объявленные с помощью ключевых слов «let» и «const») внутри блока ({ }), доступны только внутри него.

Область видимости — это также набор правил, по которым осуществляется поиск переменной. Если переменной не существует в текущей области видимости, ее поиск производится выше, во внешней по отношению к текущей области видимости.

Что такое замыкание (Closures)?

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

Как проверить, является ли значение ложным?

Следует использовать функцию Boolean или оператор “!!” (двойное отрицание).

Для чего используется директива «use strict»?

«use strict» — это директива ES5, которая заставляет весь наш код или код отдельной функции выполняться в строгом режиме. Строгий режим вводит некоторые ограничения по написанию кода, тем самым позволяя избегать ошибок на ранних этапах.

Вот какие ограничения накладывает строгий режим.

Нельзя присваивать значения или обращаться к необъявленным переменным

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

var NaN = NaN

Нельзя удалить «неудаляемое» свойство объекта

delete obj.x

Запрещено дублирование параметров

Нельзя создавать функции с помощью функции eval

Значением «this» по умолчанию является undefined

Какое значение имеет this?

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

const carDetails = {
    name: 'Ford Mustang',
    yearBought: 2005,
    getName() {
        return this.name
    }
    isRegistered: true
}

var name = 'Ford Ranger'
var getCarName = carDetails.getName

console.log(getCarName()) // Ford Ranger

Причина такого поведения заключается в том, что «владельцем» getCarName является объект window. Переменные, объявленные с помощью ключевого слова «var» в глобальной области видимости, записываются в свойства объекта window.

Одним из способов решения данной проблемы является использование методов call или apply:

console.log(getCarName.apply(carDetails)) // Ford Mustang console.log(getCarName.call(carDetails)) /

Что такое прототип объекта?

Это план объекта.

Это также один из способов обмена свойствами и функциональностью между объектами.

Если определенного свойства нет в объекте, его поиск осуществляется сначала в прототипе объекта, затем в прототипе прототипа объекта и так до тех пор, пока свойство не будет найдено. Это называется цепочкой прототипов. На вершине цепочки прототипов находится Object.prototype.

Что такое IIFE?

IIFE или Immediately Invoked Function Expression — это функция, которая вызывается или выполняется сразу же после создания или объявления. Для создания IIFE необходимо обернуть функцию в круглые скобки (оператор группировки), превратив ее в выражение, и затем вызвать ее с помощью еще одних круглых скобок. Это выглядит так: (function(){})().

Лучшее использование IIFE — это выполнение функций настройки инициализации и предотвращение конфликтов имен с другими переменными в глобальной области видимости (загрязнение глобального пространства имен).

Если ее использовать в цикле, IIFE создает новую область видимости на каждой итерации.

Для чего используется метод Function.prototype.apply

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

const details = {
    message: 'Hello World!'
}

function getMessage() {
    return this.message
}

getMessage.apply(details)

Отличие call и apply состоит в том, что в apply аргументы передаются в виде массива.

greeting.apply(person, ['Hello'])

В call через запятую.

greeting.call(person, 'Hello');

Для чего используется метод Function.prototype.bind?

Bind возвращает новую функцию, значением this которой является объект, указанный в качестве первого параметра. В отличие от bind, call и apply сразу же вызывают функцию.

this.handleChange = this.handleChange.bind(this)

Что такое функциональное программирование и какие особенности JS позволяют говорить о нем как о функциональном языке программирования?

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

Объект Array содержит методы map, filter и reduce, которые являются самыми известными функциями в мире функционального программирования из-за их полезности, а также потому, что они не изменяют массив, что делает эти функции «чистыми».

Что делает метод reduce?

Метод reduce выполняет callback один раз для каждого элемента массива, за исключением пустот, принимая четыре аргумента: начальное значение (или значение от предыдущего callback), значение текущего элемента, текущий индекс и итерируемый массив:

const strs = ['I', ' ', 'am', ' ', 'Iron', ' ', 'Man']

const result = strs.reduce((acc, currentStr) => acc + str, '')

Что такое функции высшего порядка (Higher Order Functions)?

Функция высшего порядка — это функция, возвращающая другую функцию или принимающая другую функцию в качестве аргумента.

Почему функции в JS называют объектами первого класса (First-class Objects)?

Функции называют объектами первого класса, потому что они обрабатываются также, как и любое другое значение в JS. Они могут присваиваться переменным, быть свойством объекта (методом), элементом массива, аргументом другой функции, значением, возвращаемым функцией. Единственным отличием функции от любого другого значения в JS является то, что функция может быть выполнена или вызвана.

Как бы Вы реализовали метод Array.prototype.map?

function map(arr, mapCallback) {
    // проверяем переданные параметры
    if (!Array.isArray(arr) || !arr.length || typeof mapCallback !== 'function') {
        return []
    } else {
        let result = []
        // мы создаем массив с результатами при каждом вызове функции
        // поскольку мы не хотим менять оригинальный массив
        for (let i = 0, len = arr.length; i < len; i++) {
            result.push(mapCallback(arr[i], i, arr))
            // помещаем результаты mapCallback в result
        }
        return result
    }
}

Как бы Вы реализовали метод Array.prototype.filter?

function filter(arr, filterCallback) {
    // проверяем передаваемые параметры
    if (!Array.isArray(arr) || !arr.length || typeof filterCallback !== 'function') {
        return []
    } else {
        let result = []
        // ...
        for (let i = 0, len = arr.length; i < len; i++) {
            // определяем соответствие возвращаемого результата заданному условию
            if (filterCallback(arr[i], i, arr)) {
                // помещаем значение, прошедшее фильтр, в result
                result.push(arr[i])
            }
        }
        return result
    }
}

Как бы Вы реализовали метод Array.prototype.reduce?

function reduce(arr, reduceCallbak, initialValue) {
    // ..
    if (!Array.isArray(arr) || !arr.length || typeof filterCallback !== 'function') {
        return []
    } else {
        // если в функцию не было передано значения initialValue, то
        let hasInitialValue = initialValue !== undefined
        let value = hasInitialValue ? initialValue : arr[0]
        // мы будем использовать первый элемент initialValue

        // затем мы перебираем массив, начиная с 1, если в функцию не передавалось значения initialValue, либо с 0, если значение было передано
        for (let i = hasInitialValue ? 0 : 1, len = arr.length; i < len; i++) {
            // затем на каждой итерации мы присваиваем результат вызова reduceCallback переменной
            value = reduceCallback(value, arr[i], i, arr)
        }
        return value
    }
}

Что такое объект arguments?

Arguments — это коллекция аргументов, передаваемых функции. Это объект, подобный массиву, у него есть свойство length, мы можем получить доступ к определенному значению с помощью arguments[i], но у него отсутствуют методы forEach, reduce, filter и map. Он позволяет узнать количество параметров функции.

Запомните: в стрелочных функциях объект arguments не работает.

Как создать объект, не имеющий прототипа?

Это можно сделать с помощью Object.create:

const o1 = {}
console.log(o1.toString) // [object Object]

const o2 = Object.create(null) // в качестве первого параметра методу Object-create передается объект-прототип
// нам не нужен объект-прототип, поэтому передаем null
console.log(o2.toString) // o2.toString is not a function

Что такое 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 - видны в функциях, перестают существовать после их завершения.

«let» и «const» - в блоках.

Что такое стрелочные функции (Arrow Functions)?

Стрелочная функция — это относительно новый способ создания функций в JS. Стрелочные функции создаются быстрее и имеют более читаемый синтаксис.

Cтрелочные функции неявно возвращают значения при условии, что мы возвращаем одно выражение или значение

Что такое классы (Classes)?

Это синтаксический сахар для функций-конструкторов. В основе классов лежат те же прототипы и прототипное наследование.

Что такое шаблонные литералы (Template Literals)?

Шаблонные литералы создаются с помощью двойных обратных кавычек (``)

Что такое деструктуризация объекта (Object Destructuring)?

Деструктуризация — относительно новый способ получения (извлечения) значений объекта или массива.

Использование деструктуризации позволяет сделать код чище и отнимает меньше времени.

const employee = {
    firstName: 'Marko',
    lastName: 'Polo',
    position: 'Software Developer',
    yearHired: 2017
}

let { firstName, lastName, position, yearHired } = employee

Что такое модули (Modules)?

Модули позволяют объединять (использовать) код из разных файлов и избавляют нас от необходимости держать весь код в одном большом файле.

До появления модулей в JS существовало две популярные системы модулей для поддержки кода:

CommonJS — Nodejs

AMD (AsyncronousModuleDefinition) — Browsers

Синтаксис модулей очень простой: мы используем import для импорта функциональности или значений из другого файла или файлов и export для экспорта.

// ES5 CommonJS - helpers.js
exports.isNull = function(val){
    return val === null
}

// ES6 модули
export function isNull(val){
    return val === null;
}

Что такое объект Set?

Объект Set позволяет хранить уникальные значения, примитивы и ссылки на объекты.

const set2 = new Set(['a','b','c','d','d','e']) // вторая "d" не добавится
set2.add('g').add('h').add('i').add('j').add('k').add('k') // вторая "k" не добавится
set2.delete('z')
set2.has('a')
set2.size // 10
set2.clear()

Мы можем использовать Set для удаления повторяющихся значений в массиве:

const nums = [1,2,3,4,5,6,6,7,8,8,5]
const uniqNums = [...new Set(nums)] // [1,2,3,4,5,6,7,8]

Что такое функция обратного вызова (Callback Function)?

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

const btnAdd = document.getElementById('btnAdd')

btnAdd.addEventListener('click', function clickCallback(e)){
    // делаем нечто полезное
}

Что такое промисы (Promises)?

Промисы — это один из приемов работы с асинхронным кодом в JS. Они возвращают результат асинхронной операции. Промисы были придуманы для решения проблемы так называемого «ада функций обратного вызова».

У промиса есть четыре состояния:

Ожидание — начальное состояние промиса. Результата промиса неизвестен, поскольку операция не завершена.

Выполнено — асинхронная операция выполнена, имеется результат.

Отклонено — асинхронная операция не выполнена, имеется причина.

Завершено — выполнено или отклонено.

В качестве параметров конструктор промиса принимает resolve и reject. В resolve записывается результат выполнения операции, в reject — причина невыполнения операции. Результат может быть обработан в методе .then, ошибка — в методе .catch. Метод .then также возвращает промис, поэтому мы можем использовать цепочку, состоящую из нескольких .then.

Что такое async/await?

Async/await — относительно новый способ написания асинхронного (неблокирующего) кода в JS. Им оборачивают промис. Он делает код более читаемым и чистым, чем промисы и функции обратного вызова. Однако для использования async/await необходимо хорошо знать промисы.

Использование ключевого слова «async» перед функцией заставляет ее возвращать промис

В чем разница между spread-оператором и rest-оператором?

Операторы spread и rest имеют одинаковый синтаксис (“…”). Разница состоит в том, что с помощью spread мы передаем или распространяем данные массива на другие данные, а с помощью rest — получаем все параметры функции и помещаем их в массив (или извлекаем часть параметров).

function add(a, b){
    return a + b
}

const nums = [5, 6]
const sum = add(...nums)

function add(...rest){
    return rest.reduce((total, current) => total + current)
}

Что такое объектная обертка (Wrapper Objects)?

Временное преобразование в объект.

let name = 'marko'

console.log(typeof name) // string
console.log(name.toUpperCase()) // MARKO

Name — это строка (примитивный тип), у которого нет свойств и методов, но когда мы вызываем метод toUpperCase(), это приводит не к ошибке, а к «MARKO».

Причина такого поведения заключается в том, что name временно преобразуется в объект. У каждого примитива, кроме null и undefined, есть объект-обертка.

Что такое NaN? Как проверить, является ли значение NaN?

NaN или Not A Number (не число) — это значение, получаемое в результате выполнения числовой операции над нечисловым значением.

Как проверить, является ли значение массивом?

Для этого следует использовать метод Array.isArray.

Как проверить, что число является четным, без использования деления по модулю или деления с остатком (оператора “%”)?

Как определить наличие свойства в объекте?

Первый способ состоит в использовании оператора «in»:

const o = {
    'prop': 'bwahahah',
    'prop2': 'hweasa'
}

console.log('prop' in o) // true
console.log('prop1' in o) // false

Второй — использовать метод hasOwnProperty:

console.log(o.hasOwnProperty('prop2')) // true
console.log(o.hasOwnProperty('prop1')) // false

Третий — индексная нотация массива:

console.log(o['prop']) // bwahahah
console.log(o['prop1']) // undefined

Что такое AJAX?

AJAX или Asyncronous JavaScript and XML — это набор взаимосвязанных технологий, которые позволяют работать с данными в асинхронном режиме. Это означает, что мы можем отправлять данные на сервер и получать данные с него без перезагрузки веб-страницы.

Как в JS создать объект?

Объектный литерал:

const o = {
    name: 'Mark',
    greeting(){
        return `Hi, I'm ${this.name}`
    }
}

o.greeting // Hi, I'm Mark

Функция-конструктор:

function Person(name){
    this.name = name
}

Person.prototype.greeting = function(){
    return `Hi, I'm ${this.name}`
}

const mark = new Person('Mark')

mark.greeting() // Hi, I'm Mark

Метод Object.create:

const n = {
    greeting(){
        return `Hi, I'm ${this.name}`
    }
}

const o = Object.create(n)

o.name = 'Mark'

console.log(o.greeting) // Hi, I'm Mark

В чем разница между методами Object.freeze и Object.seal?

Разница заключается в том, что при использовании метода Object.freeze мы не можем менять или редактировать свойства объекта, а при использовании Object.seal у нас такая возможность имеется.

В чем разница между оператором «in» и методом hasOwnProperty?

Отличие состоит в том, что оператор «in» проверяет наличие свойства не только в самом объекте, но и в его прототипах, а метод hasOwnProperty — только в объекте.

Какие приемы работы с асинхронным кодом в JS Вы знаете?

Функции обратного вызова (Callbacks).

Промисы (Promises).

Async/await.

Библиотеки вроде async.js, blueprint, q, co.

В чем разница между обычной функцией и функциональным выражением?

Допустим, у нас есть следующее:

hoistedFunc()
notHoistedFunc()

function hoistedFunc(){
    console.log('I am hoisted')
}

var notHoistedFunc = function(){
    console.log('I will not be hoisted!')
}

Вызов notHoistedFunc приведет к ошибке, а вызов hoistedFunc нет, потому что hoistedFunc «всплывает», поднимается в глобальную область видимости, а notHoistedFunc нет.

Как в JS вызвать функцию?

В JS существует 4 способа вызвать функцию. Вызов определяет значение this или «владельца» функции.

Вызов в качестве функции. Если функция вызывается как метод, конструктор или с помощью методов apply или call, значит она вызывается как функция. Владельцем такой функции является объект window:

function add(a,b){
    console.log(this)
    return a + b
}

add(1,5) // window, 6

const o = {
    method(callback){
        callback()
    }
}

o.method(function(){
    console.log(this) // window
})

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

const details = {
    name: 'Marko',
    getName(){
        return this.name
    }
}

details.getName() // Marko, значением this является объект details

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

function Employee(name, position, yearHired){
    // создается пустой объект, являющийся значением this
    // this = {}
    this.name = name
    this.position = position
    this.yearHired = yearHired
    // наследование от Employee.prototype неявно возвращает this, если не указано иное
}

const emp = new Employee('Marko Polo', 'Software Development', 2017)

Вызов с помощью методов apply или call. Мы используем эти методы, когда хотим явно определить значение this или владельца функции:

const obj1 = {
    result: 0
}

const obj2 = {
    result: 0
}

function reduceAdd(){
    let result = 0
    for(let i = 0, len = arguments.length; i < len; i++){
        result += arguments[i]
    }
    this.result = result
}

reduceAdd.apply(obj1, [1,2,3,4,5]) // значением this является obj1
reduceAdd.call(obj2, 1,2,3,4,5) // значением this является obj2

Что такое запоминание или мемоизация (Memoization)?

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

Как бы Вы реализовали вспомогательную функцию запоминания?

function memoize(fn){
    const cache = {}
    return function(param){
        if(cache[param]){
            console.log('cached')
            return cache[param]
        } else{
            let result = fn(param)
            cache[param] = result
            console.log('not cached')
            return result
        }
    }
}

const toUpper = (str = '') => str.toUpperCase()

const toUpperMemoized = memoize(toUpper)

toUpperMemoized('abcdef')
toUpperMemoized('abcdef') // не выполнится

Почему typeof null возвращает object? Как проверить, является ли значение null?

typeof null == ‘object’ всегда будет возвращать true по историческим причинам. Поступало предложение исправить эту ошибку, изменив typeof null = ‘object’ на typeof null = ‘null’, но оно было отклонено в интересах сохранения обратной совместимости (такое изменение повлекло бы за собой большое количество ошибок).

Для проверки, является ли значение null можно использовать оператор строгого равенства (===)

Для чего используется ключевое слово «new»?

Ключевое слово «new» используется в функциях-конструкторах для создания нового объекта (нового экземпляра класса).

Ключевое слово «new» делает 4 вещи:

Создает пустой объект.

Привязывает к нему значение this.

Функция наследует от functionName.prototype.

Возвращает значение this, если не указано иное.

Что такое DOCTYPE и зачем он нужен?

Строчка с DOCTYPE (Document Type Definition) в начале HTML страницы указывает на тип документа, который вы будете использовать при написании HTML кода для вашего сайта. Это непарный тег, то есть у него нет закрывающего тега.

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

Для чего хороши атрибуты data-?

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

<div data-fluid>Содержимое</div>

Теперь можем в стилях обратиться к этому элементу как div[data-fluid]

Javascript.

var el = document.getElementById('user');
id = el.dataset.id; // Получаем значение атрибута data-id

Что такое прогрессивный рендеринг?

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

Примеры таких методов:

Ленивая загрузка изображений, где (как правило) некоторые javascript загружают изображение, когда оно попадает в окно просмотра браузеров, вместо загрузки всех изображений при загрузке страницы.

Приоритет видимого содержимого (или выше рендеринга сложения), где вы включаете только минимальные css/content/скрипты, необходимые для количества страницы, которая будет отображаться в чтобы браузер отображался как можно быстрее, вы можете использовать отложенный javascript (domready/load) для загрузки других ресурсов и контента.

Как this работает в классах, а как – в функциях?

function test() {
  return this;
}
test()

Вызовет глобальный объект тк this не в объекте.

В объекте.

var person = {
  first: 'John',
  last: 'Smith',  
  full: function() {
    console.log(this.first + ' ' + this.last);
  }
};
person.full();

Значение this выставляется в соответствии с ближайшим родительским объектом, который вызывает метод

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

function Car(make, model) {
  this.make = make;
  this.model = model;
};

var myCar = new Car('Ford', 'Escape');
console.log(myCar);
// logs => Car {make: "Ford", model: "Escape"}

Чем отличаются собственные объекты (native objects) и объекты хоста (host objects)?

Тем что host объекты это те, которые предоставляются контекстом выполнения.

Как в JavaScript работает прототипное наследование (prototypal inheritance).

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

Когда мы хотим прочитать свойство из object, а оно отсутствует, JavaScript автоматически берёт его из прототипа.

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

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

let animal = {
  eats: true
};
let rabbit = {
  jumps: true
};

rabbit.__proto__ = animal;

Свойство proto — исторически обусловленный геттер/сеттер для Prototype.

Свойство proto считается устаревшим, и по стандарту оно должно поддерживаться только браузерами.

Современные же методы это:

Object.create(proto, [descriptors]) – создаёт пустой объект со свойством [[Prototype]], указанным как proto, и необязательными дескрипторами свойств descriptors. Object.getPrototypeOf(obj) – возвращает свойство [[Prototype]] объекта obj. Object.setPrototypeOf(obj, proto) – устанавливает свойство [[Prototype]] объекта obj как proto.

Прототипы никак не влияют на this.

Неважно, где находится метод: в объекте или его прототипе. При вызове метода this — всегда объект перед точкой.

Таким образом, вызов сеттера admin.fullName= в качестве this использует admin, а не user.

Если в F.prototype содержится объект, оператор new устанавливает его в качестве Prototype для нового объекта.

let animal = {
  eats: true
};

function Rabbit(name) {
  this.name = name;
}

Rabbit.prototype = animal;

let rabbit = new Rabbit("White Rabbit");

Установка Rabbit.prototype = animal буквально говорит интерпретатору следующее: “При создании объекта через new Rabbit() запиши ему animal в Prototype.

У каждой функции по умолчанию уже есть свойство “prototype”.

По умолчанию “prototype” – объект с единственным свойством constructor, которое ссылается на функцию-конструктор (саму функцию).

Что такое тернарный оператор?

условие ? выражение1 : выражение2

Это единственный оператор с тремя аргументами, что отражено в названии.

Первый аргумент — это условие. Если оно истинно (равно true), оператор вернёт второй аргумент — выражение1.

В ином случае он вернёт третий аргумент — выражение2.

Какие способы создания массива.

a = [1,2,3]
a = new Array(1,2,3)

Способы создания объекта.

Литеральная нотация

var someObject_1 = {};

Конструктор Object

var someObject_2 = new Object();

var someObject_2 = {
    name: "Nick",
    age: 30,
    jump: function(){
        console.log("jump");
    }
};

Функция конструктор

function SomeObject_3(name, age){
    this.name = name;
    this.age = age;
}

SomeObject_3.prototype.run = function(){
    console.log("run");
}

Метод Object.create()

var someObject_4 = Object.create(Object.prototype);

// the full analogue of Object.create (Object.prototype) is
var someObject_4 = {};

//object without prototype
var someObject_4 = Object.create(null);

С помощью классов

class SomeObject_4{

    constructor(name, age){
        this.name = name;
        this.age = age;
    }

    run(){
        console.log("run");
    }
}


let someObject_4 = new SomeObject_4("Alex", 20);

типы данных

число

строка

булево

null

undefined

symbol - уникальный идентификатор

объект

Отличие for..of от for…in

for..of - проходит по итерируемому объекту как массив

for .. in - проходит по свойствам объекта

Отличие Object.getOwnPropertyNames и Object.keys

Object.getOwnPropertyNames(a) - возвратит ВСЕ свойства.

Object.keys(a) возвратит только перечисляемые свойства.

var a = {};
Object.defineProperties(a, {
    one: {enumerable: true, value: 'one'},
    two: {enumerable: false, value: 'two'},
});
Object.keys(a); // ["one"]
Object.getOwnPropertyNames(a); // ["one", "two"]

Object.getOwnPropertyNames method will return an extra property that is length.

Что делает Object.assign().

Он копирует все не унаследованные свойства объекта в целевой объект.

const target = { a: 1, b: 2 };
const source = { b: 4, c: 5 };

const returnedTarget = Object.assign(target, source);

В чём разница между императивным и декларативным программированием?

Императивное программирование касается того, как делать.

const sumArray = array => {
  let result = 0;
  for (let i = 0; i < array.length; i++) { 
    result += array[i]
  }; 
  return result;
}

Декларативное программирование сосредотачивается на том, что делать.

const sumArray = array => { return array.reduce((x, y) => x + y) };

Объясните делегирование событий.

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

Преимущества этого приёма:

Экономит объем используемой памяти, т.к. для родительского элемента требуется только один обработчик.

Не нужно привязывать или убирать обработчики при добавлении и удалении элементов.

Как this работает в JavaScript

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

Если для вызова/создания функции используются apply, call или bind, то this внутри функции — это объект, который передается в качестве аргумента.

Если функция вызывается как метод, например, obj.method(), то this — это объект, к которому принадлежит функция.

Если функция вызывается без контекста, то есть она вызывается без условий, описанных в пунктах выше, то this является глобальным объектом. В браузере это объект window. В строгом режиме (’use strict’), this будет undefined вместо глобального объекта.

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