Не так давно озадачился поиском работы, в связи с чем посетил n-нное количество собеседований и услышал много интересных вопросов. По сети гуляет много статей с вопросами по JS, поэтому постараюсь выбрать вопросы, которые ещё не видел. Здесь нет вопросов типа Что такое замыкание?, Наследование в JavaScript или Сделайте ajax запрос на VanillaJS. Кстати советую поискать ответы на эти вопросы, прежде чем читать статью :) Под катом вопросы типа «с подвохом». Вряд ли какой-то из них попадётся вам, но, надеюсь, статья настроит вас на «подвоховое» мышление, и напомнит некоторые скользкие места и подводные камушки javascript.
Hoisting — всплытие переменных объявленных в функции.Здесь можно подробно узнать о том как это бывает.
А вот интересный вопрос:
Что мы увидим в консоли?
Если вы сходу уловили подвох предыдущей задачи — не обольщайтесь. Вот ещё интересный пример кода:
Что теперь мы увидим в консоли?
Ну и напоследок. Напомню советы Дугласа Крокфорда: избегать слабых сторон языка и использовать сильные и использовать JSLint.
Чтобы не наткнуться на такие сюрпризы можно взять за привычку самому выносить var в начало функции и объявлять функцию через function expression
Наверное все знают что все объекты передаются в javascript по ссылке:
Не знаю как вы, а я засыпался на этом вопросе. Я точно знал что объект не измениться после вызова функции, но объяснить почему так и не смог.
Контекст выполнения функции — мощный и выразительный механизм, если умело его использовать. Правда есть несколько моментов о которых не стоит забывать. Простой пример. Рассмотрим класс который логгирует некие действия.
Что будет в консоли? Как починить?
UPD: ещё набор из 5 годных интересных вопросов по теме
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 имеют больший приоритет и понимаются выше
< (function() {
var x = 1;
function x() {};
console.log(x);
})()
> undefined
1
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
UPD: ещё набор из 5 годных интересных вопросов по теме