Last active
May 18, 2018 06:40
-
-
Save egorzekov/3501b1f0a4596d6c0b7d08accfea90aa to your computer and use it in GitHub Desktop.
Interview preparation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Типы данных в JS. Приведение типов | |
*/ | |
// primitives | |
const someString = 'some_string', | |
someNumber = 12345, | |
someBoolean = true, | |
someUndefined = undefined, | |
someNull = null; | |
// object | |
const someObject = { a: 'a' }; | |
typeof someString; // 'string' | |
typeof someObject; // 'object' | |
typeof null; // 'object' - language error | |
typeof function() {}; // 'function' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Что такое hoisting? | |
*/ | |
// Всплытие объявления переменных вверх. Пример: | |
console.log(a); // undefined | |
console.log(b); // function body | |
console.log(c); // undefined | |
b() // 'b function' | |
c() // TypeError - not a function (it's undefined) | |
var a = 2; | |
// Function Declaration | |
function b() { | |
console.log('b function'); | |
} | |
// Function Expression | |
var c = function() { | |
console.log('c function'); | |
} | |
console.log(a); // 2 | |
console.log(b); // function body | |
console.log(c); // function body | |
b() // 'b function' | |
c() // 'c function' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Let vs var. Const | |
*/ | |
// ES6 (es-2015) ключевые слова для объявления переменных | |
// 1. Область видимости переменной let, const – блок {...}. | |
{ | |
var a = 'a'; | |
} | |
console.log(a); // 'a' | |
{ | |
let b = 'b'; | |
} | |
console.log(b); // ReferenceError | |
// 2. Переменная let видна только после объявления (no hoisting). | |
console.log(a); // undefined | |
var a = 'a'; | |
console.log(b); // ReferenceError | |
let b = 'b'; | |
// 3. При использовании в цикле, для каждой итерации создаётся своя переменная. | |
// 4. Объявление const задаёт константу, то есть переменную, которую нельзя менять. | |
// Т.е. нельзя менять ссылку, но если это объек или массив - можно менять свойства внутри. | |
const c = {}; | |
c = 'c'; // TypeError: Assignment to constant variable. | |
c.someKey = 'c'; | |
console.log(c); // { someKey: "c" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Передача данных по ссылке и по значению. Примеры | |
*/ | |
// Примитивы передаются (копируются) и сравниваются по значению | |
let a = 'oldA'; | |
let aCopy = a; | |
console.log(a === aCopy); // true, значения одинаковые | |
a = 'newA'; | |
console.log(a); // 'newA' | |
console.log(aCopy); // 'oldA' | |
// Объекты передаются (копируются) и сравниваются по ссылке | |
let a = { someKey: 'someValue' }; | |
let aCopy = a; | |
console.log(a === aCopy); // true, ссылаются на одно значение | |
a = { someKey: 'someValue' }; // Т.к. aCopy ссылается на a, изменения каснутся обоих объектов | |
console.log(a); // { someKey: 'someValue' } | |
console.log(aCopy); // { someKey: 'someValue' } | |
/* | |
{a: 10} == {a: 10}. Что вернет код? | |
*/ | |
// false, т.к. сравнение объектов просходит по ссылке, а каждый литерал объекта ссылается на уникальное место в памяти |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Что такое this? | |
*/ | |
// Значение this называется контекстом вызова и будет определено в момент вызова функции. | |
// https://learn.javascript.ru/object-methods#%D0%BF%D0%BE%D0%B4%D1%80%D0%BE%D0%B1%D0%BD%D0%B5%D0%B5-%D0%BF%D1%80%D0%BE-this | |
/* | |
Apply, call, bind. Для чего используются? В чем отличия? | |
*/ | |
function show(amount, currency) { | |
console.log(this); | |
console.log(this.name); | |
console.log(`${this.name} has ${amount} ${currency}`); | |
} | |
show(12, 'USD') // ' has 12 USD' - this ссылается на глобальный объект window | |
// 1. Call - явный вызов функции с новым контекстом. Дополнительные аргументы передаются СПИСКОМ. | |
show.call({ name: 'Egor' }, 50, 'USD'); // 'Egor has 12 USD' - this ссылается на переданный объект { name: 'Egor' } | |
// 2. Apply - явный вызов функции с новым контекстом. Дополнительные аргументы передаются МАССИВОМ. | |
show.apply({ name: 'Egor' }, [50, 'USD']); // 'Egor has 12 USD' - this ссылается на переданный объект { name: 'Egor' } | |
// 3. Bind - привязка нового контекста к функции. Возвращает новую функцию. | |
const newShow = show.bind({ name: 'Egor' }) // привязываем новые контекст и сохраняем полученную функцию | |
newShow(50, 'USD'); // 'Egor has 12 USD' - this ссылается новый контекст | |
/* | |
Замыкание. Приведите пример. | |
*/ | |
// Объявленное внутри - снаружи недоступно, в то время как объявленное снаружи - доступно внутри (Lexical scoping). | |
// Функции, которые используют переменные из внешнего скоупа - это и есть замыкание (function + env). | |
// https://www.youtube.com/watch?v=71AtaJpJHw0 | |
function sumOfNumbers(passedOne) { | |
const outer = 3; | |
return function(passedTwo) { | |
return passedOne + outer + passedTwo; // outer и passedOne берутся из замыкания | |
} | |
} | |
console.log(sumOfNumbers(2)(1)); // 6 | |
/* | |
Sum(1)(2) | |
*/ | |
function sum(passed) { | |
return function(inner) { | |
return passed + inner; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Prototype. Отличия proto от prototype. Пример наследования | |
*/ | |
// 1. Объект, на который указывает ссылка __proto__, называется «прототипом». | |
// Другими словами, прототип – это «резервное хранилище свойств и методов» объекта, автоматически используемое при поиске. | |
// 2. prototype - старое св-во, которое работает во всех браузерах. proto в конструкторе не работает в IE 10. | |
// Оно по факту отрабатывает во время создания объекта через new SomeObject. | |
var animal = { | |
eats: true | |
}; | |
function Dog(isCorgy, name) { | |
this.isCorgy = isCorgy; | |
this.name = name; | |
} | |
Dog.prototype = animal; | |
var bobby = new Dog(true, 'Bobby'); | |
console.log(bobby.eats); | |
//3 Examples | |
var animal = { | |
eats: true | |
}; | |
var rabbit = { | |
jumps: true, | |
__proto__: animal | |
}; | |
// obj.hasOwnProperty(prop) - проверка, есть ли св-во в самом объекте (без поиска в прототипах) | |
console.log(rabbit.hasOwnProperty('jumps')); // true | |
console.log(rabbit.hasOwnProperty('eats')); // false | |
// | |
/* | |
Как создать объект без прототипа? | |
*/ | |
// Создание объекта без прототипа резонно, когда названия св-в - динамичны, и могут, например, приходить от пользователя. | |
// На этой почте могут быть конфликты с дефолтными св-вами и методами объекта. | |
// 1 | |
Object.create(null); | |
// 2 | |
let a = {}; | |
a.__proto__ = null; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Методы массива, перебирающие элементы массива | |
*/ | |
Array.prototype.forEach; | |
Array.prototype.map; | |
Array.prototype.filter; | |
Array.prototype.sort; | |
Array.prototype.find; | |
Array.prototype.every; | |
Array.prototype.some; | |
/* | |
“hello world”.repeating(3) -> hello world hello world hello world. Как реализовать? | |
*/ | |
// Built-in | |
String.prototype.repeat; | |
// Common style | |
String.prototype.repeating = function(number) { | |
return new Array(number + 1).join(this); | |
}; | |
// Arrow function style | |
String.prototype.repeating = (number) => new Array(number + 1).join(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Браузерные события элементов. Отмена дефолтных событий браузера | |
*/ | |
// 1. EVENTS | |
// Mouse: click, contextmenu, mouseover, mousedown, mouseup, mousemove | |
// Form: submit | |
// Iput: focus | |
// Keyboard: keydown, keyup | |
// Content: DOMContentLoaded | |
// Любое событие может иметь обработчик. Они добавляются: | |
// а. С помощью HTML атрибута (не рекомендуется - разделение ответственности, не знают о перехвате) | |
//<input type="button" onclick="alert('Клик!')" value="Кнопка"/> | |
// б. С помощью свойства DOM-объекта (не рекомендуется - можно повесить только один обработчик, не знают о перехвате) | |
document.getElementById('someButton').onclick = function() { | |
console.log('Clicked'); | |
}; | |
// в. С помощью addEventListener и removeEventListener интерфейса (современный способ) | |
function clickHandler() { | |
console.log('Clicked'); | |
} | |
document.getElementById('someButton').addEventListener('click', clickHandler); | |
document.getElementById('someButton').removeEventListener('click', clickHandler); | |
// В IE8 - это соотв. методы attachEvent и detachEvent, но в них нет контекста. | |
// Отмена дефолтных событий браузера | |
// a. event.preventDefault(); | |
// б. вернуть false; | |
// в. в EI8 - event.returnValue = false; | |
/* | |
Всплытие и перехват событий | |
*/ | |
// Кликая по некому вложенному элементу, помимо запуска его обработчка, будут вызваны обработчики всех его родительских элементов (если у них есть обработчики). | |
// Стандарт выделяет 3 стадии прохода события: | |
// Перехват - событие идёт сверху (от родителей) вниз (к ребёнку, который являтся целью). | |
// Цель - событие достигло целевого элемента, идёт его обработка. | |
// Всплытие - событие идёт сверху (от родителей) вниз (к ребёнку, который являтся целью). | |
// Чтобы поймать событие на стадии перехвата, нужно использовать третий аргумент addEventListener: | |
// a. Если аргумент true, то событие будет перехвачено по дороге вниз. | |
// b. Если аргумент false, то событие будет поймано при всплытии. | |
// Каждый обработчик имеет доступ к свойствам события: | |
event.target // самый глубокий элемент, на котором произошло событие. | |
event.currentTarget // (=this) - элемент, на котором в данный момент сработал обработчик (до которого «доплыло» событие). | |
/* | |
Делегирование. Пример | |
*/ | |
// Делигирование отлично подходит, если есть много элементов, обработка которых очень схожа. | |
// Алгоритм: | |
// 1. Вешаем обработчик на контейнер. | |
// 2. В обработчике: получаем event.target. | |
// 3. В обработчике: если event.target или один из его родителей в контейнере (this) – интересующий нас элемент – обработать его. | |
` | |
<div id="menu"> | |
<button data-action="save">Сохранить</button> | |
<button data-action="load">Загрузить</button> | |
<button data-action="search">Поиск</button> | |
</div> | |
` | |
var actionMapping = { | |
save: function() {}, | |
load: function() {}, | |
search: function() {}, | |
}; | |
document.getElementById('menu').addEventListener('click', function() { | |
const action = event.target.dataset.action; | |
if (action) { | |
actionMapping[action](); | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Напишите функцию F, так чтобы new F === F | |
*/ | |
// 1 | |
const f = function() {}; | |
console.log(f === f); // true | |
// 2 | |
function F() { | |
if (!F.instance) { | |
F.instance = this | |
} | |
this.x = 'x'; | |
return F.instance; | |
} | |
console.log(F === F); // true | |
console.log(new F() === new F()); // true | |
const a = new F(); | |
const b = new F(); | |
console.log(a === b); // true | |
/* | |
Function.prototype.bind polyfill | |
*/ | |
Function.prototype.bind = Function.prototype.bind || function() { | |
const fn = this; | |
const args = Array.prototype.slice.call(arguments); | |
const newContext = args.shift(); | |
return function() { | |
return fn.apply(newContext, args); | |
}; | |
}; | |
/* | |
Object.create polyfill | |
*/ | |
Object.create = Object.create || function(parent, props) { | |
function F() { | |
F.prototype = parent; | |
if (typeof 'props' === 'object') { | |
for (prop in props) { | |
if (props.hasOwnProperty(prop)) { | |
F[prop] = props[prop]; | |
} | |
} | |
} | |
} | |
return new F(); | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Event loop | |
*/ | |
// HEAP - memory allocation | |
// CALL STACT - execution contexts | |
// WEB (C++) APIs - do some work in paralel and send to CALLBACK QUEUE | |
// CALLBACK (TASK) QUEUE - queue of items should be executed once stack gets empty | |
// EVENT LOOP - If stack is empty and callback queue is not, take the first item from the queue and push to the stack. | |
// Филип Робертс - What the heck is the event loop anyway? JSconf 2014 | |
// https://www.youtube.com/watch?v=8aGhZQkoFbQ | |
/* | |
Promises | |
*/ | |
// https://www.youtube.com/watch?v=vNEDPtVchfw | |
// https://www.youtube.com/watch?v=SjNmkeUpQAU&t | |
// 3 состояния - pending, resolved, rejected | |
function applyForVisa(documents) { | |
console.log('Обработка заявления на визу'); | |
return new Promise(function(resolve, reject) { | |
setTimeout(function() { | |
resolve({ visa: 'someVise' }); | |
}, 2200) | |
}); | |
} | |
function getVisa(visa) { | |
console.log('Виза получена'); | |
return new Promise(function(resolve, reject) { | |
resolve(visa); | |
}); | |
} | |
function bookHotel(visa) { | |
console.log('Бронируем отель'); | |
return {}; | |
} | |
function buyTickets(booking) { | |
console.log('Покупаем билеты'); | |
} | |
applyForVisa('') | |
.then((visa) => console.log(visa)) | |
.then(bookHotel) | |
.then(buyTickets) | |
.catch(err => console.log(err)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment