Практические задания на собеседование: CORE JS

Практические задания на собеседование: CORE JS

Front-end 12.09.2019

Что выведется в консоль?

1.

let a = null + undefined;
console.log(a); // NaN 

a = 13 + undefined;
console.log(a); // NaN 

a = 13 + null;
console.log(a); // 13

a = 100/0;
console.log(a); // Infinity

a = 100 * 'aaa';
console.log(a); // NaN

a = Math.sqrt(-4);
console.log(a); // NaN

2.Следующая задачка потребует немного больше внимания и объяснений

let a = (1,5 - 1) * 2;

console.log(a); // 8

Как “8”, спросите Вы? Все совершенно верно, если обратить внимание на знаки, ведь в JS число 1.5 должно быть написано через точку, а не через запятую. Здесь запятая, в свою очередь делает совершенно другое действие – она вычисляет все операнды слева на право и возвращает значение последнего из них, таким образом эта 1,5 - 1 запись будет обрабатываться так 1,5 - 1 = 1, 4 = 4.

Напишите функцию сложения вида add(num1)(num2)..

Есть несколько вариантов решения этой задачи. Первый и самый простой вариант, когда мы пытаемся вызвать функцию add(5)(4)(). Что бы функцию можно было вызвать вторыми скобками – результатом вызова должна быть функция:

function add_v1(a, b) {
    let sum = a;

    let makeSum = function (b) {
        if (b) {
            sum += b;
            return makeSum;
        } else {
            return sum;
        }
    }

    return makeSum;
}

console.log(add_v1(2)(5)(7)()); // 14

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

Теперь усовершенствуем нашу функцию, что бы была возможность вызывать ее и с 1 и с большим количеством аргументов. Для этого будем работать с массивом arguments и при любом вызове функции циклом будем суммировать полученные аргументы:

function add_v2() {
    let sum = 0;

    for (let i = 0; i < arguments.length; i++) {
        sum += arguments[i]
    }

    let makeSum = function () {
        if (arguments.length) {
            for (let i = 0; i < arguments.length; i++) {
                sum += arguments[i]
            }

            return makeSum;
        } else {
            return sum;
        }
    }

    return makeSum;
}

console.log(add_v2(2,1)(5)(5,6)(1)(7,1,1)()); // 29

Однако, если Вы захотите убрать лишние скобки в конце вызова функции, заменив вызов add(5)(4)() на add(5)(4), Вам нужно научить функцию makeSum возвращать число, для этого добавим ей метод toString в котором вернем полученную сумму.

function add_v3() {
    let sum = 0;

    for (let i = 0; i < arguments.length; i++) {
        sum += arguments[i]
    }

    let makeSum = function () {
        if (arguments.length) {
            for (let i = 0; i < arguments.length; i++) {
                sum += arguments[i]
            }

            return makeSum;
        } else {
            return sum;
        }
    }

    makeSum.toString = function () {
        return sum
    }

    return makeSum;
}
console.log(add_v3(2,1)(5)(5,6)(1)(7)); // 27

Что выведется в консоль?

Рассмотрим еще несколько интересных задачек на console.log:
1.

var a={},
    b={key:'b'},
    c={key:'c'};

a[b]=1;
a[c]=2;

console.log(a[b]); //2 

Когда у объекта устанавливается новое свойство, JS неявно сделает stringify значения. В коде выше b и c являются объектами, следовательно они оба конвертируются в "[object Object]" (String) и код выше обработается так:

var a={},
    b='object',
    c='object';

a[b]=1;
a[c]=2;

А так как полученные при помощи stringify значения равны – мы присваиваем новое значение одному и тому же свойству.
Когда у объекта устанавливается новое свойство, JS неявно сделает stringify значения. В коде выше b и c являются объектами, следовательно они оба конвертируются в "[object Object]" (String) и код выше обработается так:

var a={},
    b='object',
    c='object';

a[b]=1;
a[c]=2;

А так как полученные при помощи stringify значения равны – мы присваиваем новое значение одному и тому же свойству.

2.

var o = {
    name: 'Jony',
    getName: function() {
        console.log(this.name);
    }
}
o.getName(); // 'Jony'
var getName = o.getName;
getName(); // ''

Во втором случае мы получим пустую строку, так как this будет не объект o, а будет ссылаться на глобальный объект window, где нет свойства name:

var o = {
    name: 'Jony',
    getName: function() {
        console.log(this.name);
    }
}
o.getName(); // 'Jony', объект this = o
var getName = o.getName;
getName(); // '', объект this = Window

Если мы объявим глобальную переменную name, то подобный вызов выведет именно ее.

var o = {
    name: 'Jony',
    getName: function() {
        console.log(this);
        console.log(this.name);
    }
}
var getName = o.getName;
window.name = 'Joker';
getName(); // 'Joker'

Задачки с Promise

1.

Promise
    .resolve('a')
    .then((x) => {console.log(x); return 'b'})
    .then((x) => {console.log(x); return 'c'})
    .then((x) => console.log(x));
// a,b,c

2.

Promise
    .resolve()
    .then(() => console.log(1))
    .then(() => console.log(2))
    .then(() => console.log(3));

Promise
    .resolve()
    .then(() => console.log(4))
    .then(() => console.log(5))
    .then(() => console.log(6));
// 1,4,2,5,3,6

3.

Promise
    .resolve()
    .then(() => console.log(1))
    .then(() => {
        setTimeout(() => {
            console.log(2)
        }, 0)
    })
    .then(() => console.log(3));
// 1,3,2

В случае если есть setTimeout – он выполнится после всех success обработчиков, так как даже setTimeout(f, 0) опускается в конец стека для выполнения.
4.

console.log(1);

setTimeout(() => {
    console.log(2);
}, 0);

console.log(3);

Promise.resolve().then(() => {
    console.log(4);
})

console.log(5);

while('') {
    console.log(6);
}

console.log(7);

// 1, 3, 5, 7, 4, 2

console.log(6); не выведется, так как '' конвертнется в false и while('') не выполнится, но не пустая строка while('aaa') будет эквивалентна while(true) и console.log(6) будет выполнятся бесконечное количество раз после console.log(5).

Найдите средний возраст пользователей

const users = [
    {
        gender: 'male',
        age: 22,
    },
    {
        gender: 'female',
        age: 20,
    },
    {
        gender: 'male',
        age: 32,
    }
];

Подобная задача может быть решена при помощи reduce. Сначала мы получим сумму возрастов пользователей, а после посчитаем среднее число, разделив на длину массива, где reduce нам поможет сохранять значение с предыдущего вычисления.

let sumAge = users.reduce((res, current) => {
    return {
        age: res.age + current.age
    }
});

let averageAge = sumAge.age/users.length;
console.log(averageAge);

Пишите Ваши варианты решения этой задачи в комментариях 🙂

Напишите findUnique() функцию

const findUnique = (arr) => {
    return arr.filter((value, index, self) => {
        return self.indexOf(value) === index;
    })
}

let res = findUnique([10, 5, 6, 10, 6, 7]); 
// [10, 5, 6, 7]

Если Вы хотите найти только те значения, которые не повторяются:

const findUnique = (arr) => {
    return arr.filter((value, index, self) => {
        return self.indexOf(value) === index && self.lastIndexOf(value) === index;
    })
}

let res = findUnique([10, 5, 6, 10, 6, 7]); 
// [5, 7]

Напишите createCounter() функцию

const createCounter = () => {
    let i = 0;
    return () => i++;
}

let getCount = createCounter();
console.log(getCount()); //0
console.log(getCount()); //1
console.log(getCount()); //2 

Источники:
“Javascript. Подробное руководство” Дэвид Флэнаган
Современный учебник JavaScript
Веб-документация MDN
Medium

Поделиться

Отправить ответ

avatar
  Subscribe  
Notify of