Small garage of one Ford in the big internet
Задания выполняются на листке/доске, без компа.
===
)?Пример:
0 == false // true
[42] == '42' // и т.п.
typeof null === "object" // true
42 instnaceof Number // false
isPlainObject(o)
const isPlainObject = o => Object.prototype.toString.call(o) === '[object Object]'
'foo' / 2
isNan
typeof NaN // "number" охуенно?
copy(o: <any>)
для копирования объекта произвольной вложенности.
function copy(o) {
return JSON.parse(JSON.stringify(o))
}
{}
{
let x = 42
}
console.log(x) // что выведет?
Uncaught ReferenceError: x is not defined
const arr = []
arr.push(42) // Какую ошибку сгенерирует?
Object.freeze(o)
// Не знает и ладно, потом прочитает.Классика. На любом собеседованиии задают такой вопрос.
for (var i = 0; i < 10; i++) {
setTimeout(() => console.log(`i=${i}`), 3000)
}
Что будет выведено?
for (let i = 0; i < 10; i++) {
setTimeout(() => console.log(`i=${i}`), 3000)
}
for (var i = 0; i < 10; i++) {
setTimeout(function (i) {
console.log('i=' + i)
}(i), 3000)
}
'use strict'
в начале скрипта либо в начале тела функции?
'use strict'
const test = {
prop: 42,
meth() {
return this.prop
}
}
const fn = test.meth
console.log(fn())
Вариант 1 (его должны обязательно указать):
const fn = test.meth.bind(test)
Вариант 2:
const fn = () => test.meth()
Данные две переменные x = 3
и y = 5
.
Как обменять их значения без вспомогательных переменных?
[ x, y ] = [ y, x ]
Правильным так же является и ответ типа такого:
x = x ^ y
y = x ^ y
x = x ^ y
Но он для надмозгов.
// При объявлении функции с произвольным количеством аргументов
function foo(...args) {
console.log(args)
}
foo(1, 2, 3) // args будет содержать массив [1, 2, 3]
// Спреды можно использовать при передаче списка аргументов
Math.max(...[3, 5, 1])
// Является альтернативой использованию метода функции apply
Math.max.apply(null, [3, 5, 1])
const [ first, ...rest ] = [1, 2, 3, 4, 5]
console.log(first) // содержит 1
console.log(rest) // [2, 3, 4, 5]
function sleep(timeout) {
[some code]
}
// Пример использования
async run() {
console.log('Ждем 3 секунды')
await sleep(3000)
console.log('Продолжаем работу...')
}
function sleep(timeout) {
return new Promise((resolve, reject) => setTimeout(resolve, timeout))
}
Общий вид:
function* g() {
yield 'foo'
yield 'bar'
yield 'baz'
}
{ value: <any>, done: <bool> }
Ответ:
for (let it of g()) {
// ...
}
Задание: напишите с использование генераторов функцию, возвращающую числа Фиббоначи.
Ряд Фиббоначи выглядит следующим образом:
0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181, 6765, 10946, 17711, …
В нем каждое последующее число равно сумме двух предыдущих.
function* fib() {
let [ cur, next ] = [ 0, 1 ]
for (;;) {
yield cur
;[ cur, next ] = [ next, cur + next ]
}
}
Нет ни одного js-кодера, который не пытался написать свой eventEmitter.
class EventEmitter {
// ...
on(event, listener) {
// ...
}
off(event, listener) {
// ...
}
emit(event, ...args) {
// ...
}
}
const events = new EventEmitter()
events.on('greeting', name => {
console.log(`Hello ${name}!`);
})
events.emit('greeting', 'Sergey')
class EventEmitter {
// Приватные методы (NEW)
// Используем Map вместо Plain Object,
// так как у первого ключами могут быть любые объекты, а не только строки +
// не нужна проверка hasOwnProperty
#listeners = new Map()
on(event, listener) {
let listeners = this.#listeners.get(event)
if (!listeners) {
// Используем Set вместо Array, чтобы нельзя было добавить один и тот же
// обработчик два раза
listeners = new Set()
this.#listeners.set(event, listeners)
}
listeners.add(listener)
return this
}
off(event, listener) {
const listeners = this.#listeners.get(event)
if (listeners) {
listeners.delete(listener)
// Если листенеров больше не осталось, то нужно удалить ключ
if (listeners.size === 0) {
this.#listeners.delete(event)
}
}
return this
}
emit(event, ...args) {
const listeners = this.#listeners.get(event)
if (listeners) {
for (const listener of listeners) {
listener(...args)
}
}
return this
}
}
super([args])
в методе construct
класса наследникаsuper.meth
foo=bar
на неопределенный срок?document.cookie = 'foo=bar'
// Такой вариант
const c={}
document.cookie.split('; ').forEach(pair => {
const [ k, v ] = pair.split('=')
c[decodeURIComponent(k)] = decodeURIComponent(v)
})
console.log(c)
// Тру функицональщина
document.cookie.split('; ').reduce((acc, pair) => {
const [ k, v ] = pair.split('=', 2).map(decodeURIComponent)
acc[k] = v
return acc
}, {})
// С циклами не айс
// Если функция экспортируется так
export const func = () => {}
// То ее импорт выглядит так
import { func } from './lib'
// Можно импортировать под другим именем
import { func as name } from './lib'
// Можно импортировать все под определенным неймспейсом
import { * as lib } from './lib'
// Нужно упомянуть про export default
export default ...
// При его использование импортировать можно только так
import lib from './lib'
<script type="module" src="main.js"></script>
В main.js можно испортировать уже привычным образом.
[ Document | Element ].querySelector
[ Document | Element ].querySelectorAll
Как с помощью querySelector выбрать вторую колонку таблицы со значением Second?
<!doctype html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
</head>
<body>
<table>
<tr>
<td>First</td>
<td>Second</td>
<td>Third</td>
</tr>
</table>
</body>
</html>
document.querySelector('td:nth-child(2)')
document.getElementsByTagName('td')[1]