можно пример функции, которая не является «классом», если ее вызвать через new?
И таких функций много в JS, которые нельзя использовать в качестве конструктора.
Если не хочется, чтобы ф-ю вызывали в качестве конструктора, можно сделать и так:
function F () { if (this instanceof F) throw TypeError('F() is not a constructor'); }
isNaN — это функция не JavaScript, это функция на языке реализации движка JavaScript, а это две большие разницы. Так как она не реализована на JavaScript, ее свойства нельзя отнести к особенностям и возможностям языка
Допустим я понял, что вы имели в виду в первом предложении. Но вот выделенное мне не очень ясно. Можно ли сказать тоже самое про остальные объекты/функции, описанные в спеке?
Правильным ответом с вашей стороны должна была стать стрелочная функция:
Ну вот видите, сами ответили на свой вопрос. Раз знали ответ заранее, значит решили потроллить автора :)
Хотя про ES6 не было речи, стрелочная функция — хороший пример и хорошая отправная точка для обсуждения с кандидатом ES6 (и ES7, если интересуется будущим языка).
Использовать аксессор 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 работает только на конструкторах» — глупота.
Если все «классы» — это функции, можно пример функции, которая не является «классом», если ее вызвать через 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'а, а не для собеседования.
Это к тому, что не надо за пользователей решать, как им будет удобнее путём запрета почти всего, к чему они привыкли при редактировании. Поддерживаю то, что не надо блокировать paste и тем более contextmenu.
Есть один сервис приёма платежей, в котором сделали всё, чтобы пользователю было неудобно вводить номер карты: разделили на четыре инпута и запретили paste. Да ещё и добавили с полдюжины ненужных обязательных полей, которые каждый раз надо заполнять заново.
Небольшое уточнение: __proto__ — это геттер/сеттер в прототипе объекта (Object.prototype.__proto__), а не самого объекта.
var o = Object.create(null);
o.__proto__; // => undefined, потому что мы не имеем доступа к Object#__proto__
// но
Object.getPrototypeOf(o); // => null
Олег, несколько вопросов, по планам «когда» (ориентировочно), если есть такая инфа:
1. Релиз Chrome Mobile Apps на андроид
2. Dart VM в Chrome Apps
3. Полная поддержка ES6 (destructuring assignment, fat arrow functions, «class» sugar etc.). Я понимаю, что это больше к v8 вопрос, но ФФ стэйбл уже давно это поддерживает. И хотелось бы уже это видеть в v8 хотя бы в packaged apps.
Конечно, большинство бенчей — синтетика, имеющая мало общего с продакшном. На оф. сайте Редиса бенч показывает 75K rps. Да даже запас в 20К rps достаточно большинству проектов.
По остальному, как видно, тюнинг одного только редиса тянет на отдельную тему.
Redis… в отличие от memcached поддерживает постоянное хранение данных, и более сложные типы данных. Redis не поддерживает кластеризацию, так что использовать его для горизонтального масштабирования несколько затруднительно
В этих более сложных структурах и есть профит редиса. Во-вторых, видел бенчи редиса на commodity сервере в 300К RPS.
Вообще, статья не зачёт. Дальше «а файлы требующие серверной обработки пусть отсылает тяжелому Apache» можно не читать. Где про FastCGI/FPM, HHVM, грамотный тюнинг сервера, бд, правильная архитектура приложений (в которой кэширование по-умолчанию)? — с этого надо начинать.
По оптимизации я бы добавил вот ещё что: если приложение начинает разрастаться (сотни вотчеров), лучше автокомплит выделить в отдельный компонент (директиву) со своим скоупом и использовать $scope.$digest() (который обновит только скоуп компонента) вместо $scope.$apply(), который обновляет состояние всех скоупов, начиная с корня ($rootScope).
Ну почему же громкие слова? Как раз-таки я посчитал ваше утверждение "Node.js — не хайлоад-решение" — весьма смелым. Я с этим не согласен и, уверен, парни из PayPal тоже. Нода не для тяжёлой логики (и вообще чего-либо CPU-intensive), это да.
Ваша мысль понятна, для вас хайлоад определяется тяжеловестностью выполняемой логики (которую выполняют, как правило, бэкэнды). Это логично. Но вот возьмём два 8-ядерных commodity-сервера: на одном Java/C[++] обрабатывает какую-нибудь длинную очередь HD-видео от 100 клиентов, загружая под 100% все ядра; на другом крутится Нода с 7 форками (с лёгкой логикой, вроде отдачи из кэша), крутится хорошо, на 40K RPS, тоже загружая под 100% сервер. Первое — хайлоад (что очевидно), а второе тогда что, если не хайлоад?
Как тогда, по-вашему, называть, допустим, отдачу статики 15 млн. пользователям ежедневно? Ну вот нету ничего тяжелого в проекте (к примеру всякого рода t.co/bit.ly, хостеры картинок и т.п.).
То, что грамотное горизонтальное маштабирование позволяет использовать %language% — это понятно. Также понятно, что для тяжёлой логики есть JVM / .NET / компилируемые языки.
Во-вторых, скорость работы и стабильность для конечного пользователя — критически важный показатель для такой системы как PayPal (всё-таки не хостинг картинок с котиками). Ежедневно через систему проходят платежи на сотни млн. $.
Факт того, что PayPal переводит эту часть (фронты) на Ноду, вполне говорит нам, что она production ready && highload ready.
Посмотрите на гитхабе код хотя бы топ-50 проектов на JS, везде есть специфичные для JS конструкции. Да к примеру connect, express, которые используются во многих хайлоад проектах. Или Kraken @ PayPal (который переводит все свои фронты с jvm на node.js).
Ваши тесты — это сродне убрать соломинку из стога сена (в ущерб лаконичности) на фоне разницы минимум на порядок между ES5 Array[[prototype]] ф-ями forEach, map, reduce etc. и простым лупом. И что теперь, не использовать их?
Я сначала хотел спросить, чего ради вы ратуете за отказ от сахара, но потом увидел
2. Понятен абсолютному большинству программистов большинства популярных языков;
Может тогда питонистам отказаться от лямбд? А что делать тем, кто пишет на Clojure? :)
В каждом языке есть свои конвеции хорошего и понятного кода и желательно придерживаться в первую очередь их и только потом весьма абстрактной общей понимаемости.
Потому что, допустим, для поиска на клиенте по массиву в 30К+ городов есть смысл перенести поиск в воркер или использовать одно{двух}уровневый хэш или поиск чанками асинхронно (чтобы не блокировать UI) как фоллбэки. И это и есть своё кастомное решение, а для автокомплита по 100 тегам достаточно и
И таких функций много в JS, которые нельзя использовать в качестве конструктора.
Если не хочется, чтобы ф-ю вызывали в качестве конструктора, можно сделать и так:
Допустим я понял, что вы имели в виду в первом предложении. Но вот выделенное мне не очень ясно. Можно ли сказать тоже самое про остальные объекты/функции, описанные в спеке?
Ну вот видите, сами ответили на свой вопрос. Раз знали ответ заранее, значит решили потроллить автора :)
Хотя про ES6 не было речи, стрелочная функция — хороший пример и хорошая отправная точка для обсуждения с кандидатом ES6 (и ES7, если интересуется будущим языка).
instanceof
ищет прототип конструктора в цепочке прототипов объекта, сам же прототип в примере выше будет объектом:Object.create(null)
— особенный случай.Использовать аксессор Object#
__proto__
в этом случае не корректно, доступа к нему там просто нет. Поэтому иundefined
. И мы всё же обсуждаем создание объектов конструкторами, поэтому правильнее:Вы забыли про
(new F).__proto__ instanceof Object; // true
(кстати, вспомнил ещё вопрос из этой серии: объяснить почему
Object instanceof Function === Function instanceof Object; // true
)Меня бы ответ автора на 5-й вопрос устроил. Я бы, пожалуй, уточнил, что надо поменять (используя прототип), чтобы сравнение было истинным. Впрочем, с многими остальными ответами не всё так плохо. С ремаркой: если не придираться к терминологии, некоторым пробелам, путанице с неявным преобразованием (спеку почитает). Мы же понимамаем, что эти вопросы не для сеньора с серьёзным практическим/теоретическим бэкграундом? :) Хотя, как я уже писал и соглашусь с остальными, такого рода вопросы слишком оторваны от реальных задач и более уместны для квизов (just for fun).
Ну и поясните пожалуйста, почему (с практической т.з., т.е. создания объектов)
isNaN
.По вашему примеру:
;-)
А если вызвать
Array.prototype.push.call([], 42)
?Вы наверное не поняли, вопрос был на внимательность; в идеале, если кандидат сразу отметит, что определять свойство prototype в том объекте нет никакого смысла и это уловка.
Выполните свой код в глобальном контексте.
P.S. Вопросы, имхо, больше для Quiz'а, а не для собеседования.
paste
и тем болееcontextmenu
.__proto__
— это геттер/сеттер в прототипе объекта (Object.prototype.__proto__), а не самого объекта.1. Релиз Chrome Mobile Apps на андроид
2. Dart VM в Chrome Apps
3. Полная поддержка ES6 (destructuring assignment, fat arrow functions, «class» sugar etc.). Я понимаю, что это больше к v8 вопрос, но ФФ стэйбл уже давно это поддерживает. И хотелось бы уже это видеть в v8 хотя бы в packaged apps.
По остальному, как видно, тюнинг одного только редиса тянет на отдельную тему.
В этих более сложных структурах и есть профит редиса. Во-вторых, видел бенчи редиса на commodity сервере в 300К RPS.
Вообще, статья не зачёт. Дальше «а файлы требующие серверной обработки пусть отсылает тяжелому Apache» можно не читать. Где про FastCGI/FPM, HHVM, грамотный тюнинг сервера, бд, правильная архитектура приложений (в которой кэширование по-умолчанию)? — с этого надо начинать.
$scope.$digest()
(который обновит только скоуп компонента) вместо$scope.$apply()
, который обновляет состояние всех скоупов, начиная с корня ($rootScope)."Node.js — не хайлоад-решение"
— весьма смелым. Я с этим не согласен и, уверен, парни из PayPal тоже. Нода не для тяжёлой логики (и вообще чего-либо CPU-intensive), это да.Ваша мысль понятна, для вас хайлоад определяется тяжеловестностью выполняемой логики (которую выполняют, как правило, бэкэнды). Это логично. Но вот возьмём два 8-ядерных commodity-сервера: на одном Java/C[++] обрабатывает какую-нибудь длинную очередь HD-видео от 100 клиентов, загружая под 100% все ядра; на другом крутится Нода с 7 форками (с лёгкой логикой, вроде отдачи из кэша), крутится хорошо, на 40K RPS, тоже загружая под 100% сервер. Первое — хайлоад (что очевидно), а второе тогда что, если не хайлоад?
Как тогда, по-вашему, называть, допустим, отдачу статики 15 млн. пользователям ежедневно? Ну вот нету ничего тяжелого в проекте (к примеру всякого рода t.co/bit.ly, хостеры картинок и т.п.).
То, что грамотное горизонтальное маштабирование позволяет использовать %language% — это понятно. Также понятно, что для тяжёлой логики есть JVM / .NET / компилируемые языки.
Во-вторых, скорость работы и стабильность для конечного пользователя — критически важный показатель для такой системы как PayPal (всё-таки не хостинг картинок с котиками). Ежедневно через систему проходят платежи на сотни млн. $.
Факт того, что PayPal переводит эту часть (фронты) на Ноду, вполне говорит нам, что она production ready && highload ready.
П.С. Разница в 3х между, к примеру, nginx и node.js — всё-таки это как Формула 1 и, скажем, средний спорткар, но не троллейбус :).
Посмотрите на гитхабе код хотя бы топ-50 проектов на JS, везде есть специфичные для JS конструкции. Да к примеру connect, express, которые используются во многих хайлоад проектах. Или Kraken @ PayPal (который переводит все свои фронты с jvm на node.js).
Ваши тесты — это сродне убрать соломинку из стога сена (в ущерб лаконичности) на фоне разницы минимум на порядок между ES5
Array[[prototype]]
ф-ямиforEach, map, reduce
etc. и простым лупом. И что теперь, не использовать их?Я сначала хотел спросить, чего ради вы ратуете за отказ от сахара, но потом увидел
Может тогда питонистам отказаться от лямбд? А что делать тем, кто пишет на Clojure? :)
В каждом языке есть свои конвеции хорошего и понятного кода и желательно придерживаться в первую очередь их и только потом весьма абстрактной общей понимаемости.
return list.filter(function (item) { return item.indexOf(query) != -1; });