...

суббота, 4 октября 2014 г.

JavaScript. Вопросы на собеседовании

Не так давно озадачился поиском работы, в связи с чем посетил n-нное количество собеседований и услышал много интересных вопросов. По сети гуляет много статей с вопросами по JS, поэтому постараюсь выбрать вопросы, которые ещё не видел. Здесь нет вопросов типа Что такое замыкание?, Наследование в JavaScript или Сделайте ajax запрос на VanillaJS. Кстати советую поискать ответы на эти вопросы, прежде чем читать статью :) Под катом вопросы типа «с подвохом». Вряд ли какой-то из них попадётся вам, но, надеюсь, статья настроит вас на «подвоховое» мышление, и напомнит некоторые скользкие места и подводные камушки javascript.


Hoisting




Hoisting — всплытие переменных объявленных в функции.Здесь можно подробно узнать о том как это бывает.

А вот интересный вопрос:

(function() {
f();

f = function() {
console.log(1);
}
})()

function f() {
console.log(2)
}

f();


Что мы увидим в консоли?


Ответ
Объявленная в gs function f() всплывёт, соответственно при вызове f внутри анонимной функции мы увидим не ReferenceError, как кто-то мог предположить, а двойку в консоли, при повторном вызове переменная f уже ссылается на функцию которая печатает 1.

Результат:



< (function() {
f();

f = function() {
console.log(1);
}
})()

function f() {
console.log(2)
}

f();
> undefined
2
1





Если вы сходу уловили подвох предыдущей задачи — не обольщайтесь. Вот ещё интересный пример кода:



(function() {
var x = 1;

function x() {};

console.log(x);
})()


Что теперь мы увидим в консоли?


Ответ
Функции объявленный при помощи function declaration имеют больший приоритет и понимаются выше var. Поэтому интерпретатор сначала выполнит function x() {};, а затем var x = 1;

< (function() {

var x = 1;


function x() {};


console.log(x);

})()


> undefined

1




Ну и напоследок. Напомню советы Дугласа Крокфорда: избегать слабых сторон языка и использовать сильные и использовать JSLint.

Чтобы не наткнуться на такие сюрпризы можно взять за привычку самому выносить var в начало функции и объявлять функцию через function expression


Передача по ссылке


Наверное все знают что все объекты передаются в javascript по ссылке:



var obj = {
a: 1
}

(function(obj) {
obj = {
a: 2
};

})(obj);

console.log(obj.a);


Не знаю как вы, а я засыпался на этом вопросе. Я точно знал что объект не измениться после вызова функции, но объяснить почему так и не смог.


А вот почему!

При вызове анонимной функции создастся локальная переменная obj в её области видимости. А затем создаётся новый объект {a : 2}, ссылка на который попадает в локальную переменную obj, но переменная из верхнего скоупа будет всё так же ссылаться на старый объект.



Контекст выполнения


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



Logger = function(logFn) {

_logFn = logFn;

this.log = function(message) {
_logFn(new Date() + ": " + message);
}
}

var logger = new Logger(console.log);

logger.log("Hi!");
logger.log("Wazzup?");


Что будет в консоли? Как починить?


Ответ
В консоли мы увидим TypeError: Illegal invocation

А всё потому что при вызове logger.log(), контекст выполнения функции — logger

Чтобы починить можно вспомнить про встроенные методы функций .apply(), .call(), .bind()



< rightLogger = new Logger(console.log.bind(console))
> Logger {log: function}
< rightLogger.log("It's works")
> Sat Oct 04 2014 00:32:49 GMT+0400 (MSK): It's works





This entry passed through the Full-Text RSS service - if this is your content and you're reading it on someone else's site, please read the FAQ at http://ift.tt/jcXqJW.


Комментариев нет:

Отправить комментарий