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   

ссылка на оригинал статьи http://habrahabr.ru/post/239065/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *