Все, кто тут пишут про "если у них такой код — в баню такую контору" — может стоит иногда подумать, что не все в жизни может быть так прямолинейно?
Ну, то есть, есть категория задач на более практическое применение ваших знаний — например, написать какую-то ту-душку или еще что-нибудь в этом роде. Но есть и такие, где работодатель хочет "пощупать" будущего сотрудника и за другие его качества: знает ли он банальнейшую теорию (эта вот задачка решается в уме минут за 5 если вспомнить что к чему) и способен он в конце концов решать поставленные задачу вместо вот этого вот бухтения "а зачем это? да кому это нужно?". Более того, эта задача расчитана, возможно, также на то, что если ты все-таки забыл как там операторы работают и что когда присваивается (хотя ей Богу не могу себе представить человека, которому трудно это решить) — то тогда можно посмотреть как вы справляетесь с этим косяком — будете ли вы спрашивать / гуглить / ватевер. Ну, то есть, когда вам зрение проверяют на буквах, это еще не означает, что доктор долбан, потому что заставляет читать не рассказы Чехова, а какие-то никому не нужные буковки.
Мне эта задача тоже не оч, просто потому, что никакого финта ушами там делать не нужно. Вот могу подкинуть парочку тоже ориентированных на синтаксис JS:
1) В голове посчитать результат:
120 + 102 + 012 + 002 + .12 + (0,1 + 2,3)
2) Что будет в "х"?
let i
for (i = 0; i++; i < 5) {
i = i + 3
}
const x = i
Да-да, это не про солид и дядю Боба, это просто синтаксис.
Отличная работа! Сам занимаюсь многопоточными приложениями в ноде, тоже пытался решать метрики потоков, но отложилось "на потом". Поковыраюсь в вашей либе в свободное время.
Как раз сейчас создаю инфраструктуру с использованием RMQ. До этого момента вообще не имел представления как оно работает и зачем. Большое спасибо, написано все просто отлично: доступно, детально, кратко и по делу.
Запрыгивайте на эту волну хайпа! Я и вправду впечатлен Deno. После двух лет разработки и долгого пути к успеху новая среда выполнения JavaScript выглядит просто великолепно, и мне не терпится начать экспериментировать с ней. Node появился около 11 лет назад и стал новой вехой в истории JavaScript. Он сделал язык лучше, и я думаю, что мы достигли нового рубежа, пришло время Deno!
Покупай — налетай, арбуз сочный, сладкий! Падхади, дорогой, пакупай — сладкие, как мед, гладкие, как девушка! Налетай, расхватывай! Подходи народ, свой огород! половина — сахар, половина — мед!
Речь по "случайные" глобалы, а не про вообще любые. Фича настолько не выдержала проверку временем что её экстренно залатали.
Я не совсем понимаю, что такое "случайные глобалы". Единственное, что могу к этому ассоциировать, так это что-то типа:
var a = b = 3
Что, делать, конечно же, не стоит.
Да. Но я вообще про то, что на уровне движков JS всё что связано с массивами и это груда костылей. Как раз ввиду того как они устроены на уровне языка.
Видимо я в какой-то параллельной галактике живу. Работа с массивами у меня не вызывает никаких болезненных ощущений.
Фича не выдержала проверку временем. Поэтому я считаю что эта часть дизайна языка… не очень. То что она не очень не только в JavaScript, ну что ж… Но мы тут JS обсуждаем. Я полагаю ввиду того что он динамически, да ещё и слабо, типизирован, у нас эта "фича" фейлит в разы чаще, чем в других языках. Мы ловим этот NaN слишком часто. Ох уж эти мои любимые формы страховых компаний где все поля внезапно превращаются в NaN. Или интернет магазины. Да всё что угодно. В каком-то смысла NaN это такая визитная анти-карточка JS. Там где для CSS рисуют кружку с поехавшей вёрсткой, JS хейтер может просто написать NaN :D
По-моему NaN это как-раз признак дурного тона. Если он где-то вылезает, значит человек не чекает типы, не санитайзит инпуты и вообще надеется в этой жизни на то же, что и автор статьи. У меня вот NaN вылезает в продуктах раз в год при отладке и я не считаю, что это фейл языка. Если все-таки нужны ерроры, так их тоже никто не отменял:
if (Number.isNaN(someResult)) throw new Error('NaN is here, please fix me.')
Ну, кстати, this это совсем не про прототипы. This это ничего больше, чем просто контекст функции. Скажем так, специальный "нулевой" аргумент, если можно так выразится.
var никогда не брал как что-то плохое. Функциональный скоуп это не всегда плохо. Точнее даже так — не всегда удобно с let/const и блоками, хотя у них и есть свои приимущества тоже. Если уж говорить о минусах var, так это, возможно, хойстинг. И то, это, кмк, вопрос спорный.
Метки — мне тоже никогда не мешали, не вижу в них проблемы.
Типизация — есть неудобства, есть удобства. Если мы про неудобства — то есть тайпскрипт. Но вообще — большинство ошибок связанных с типами не из-за какой-то кривости этих типов, а из-за того, что программист пишет функцию, которая умеет и стринги, и намберы и массивы в одном аргументе, плюс еще внутри это добро работает с == или какой-нибудь другой бедой.
Глобалы есть во многих языках — это, опять же, вопрос адекватности программиста. В JS, тем более, есть свои инкапсулирующие способы — модули, пакеты, ну, или, на крайний случай, функциональное замыкание.
null и undefined — тоже, в принципе, логично. Undefined говорит об отсутсвии даже определения (переменной, ключа), когда null говорит о том, что в структуре определение есть, но оно равно пустому значению. Это не одно и то же.
Stdlib можно было бы сделать богаче, тут согласен.
Не совсем понял про ватерфалл.
Про паттерн-матчинг тоже не понял.
Вы про дырявость массивов, когда const arr = []; arr[999] = null?
С числами можно было бы, возможно, сделать по-элегантнее. С другой стороны, дабла в большинстве случаев вполне хватает.
NaN, если я не ошибаюсь и в других языках не ошибка. Могу ошибаться. Но в любом случае, это скорее, как мне кажется, дискуссия о IEEE-754, нежели о языке.
Многопоток достаточно просто реализуется что в вебе, что в ноде. В ноде вообще красота — они идут уже из коробки без всяких подпроцессов с, помоему, десятой версии: require('worker_threads').
Вроде же поддерживали, нет?
Коллбек API завертывается в Promises на раз-два. Конечно, лучше бы, если сразу из коробки, но это, как мне кажется, опять к фундаменту языка не имеет отношения. Скорее это про интерфейс APIшек.
JS совсем не простой язык и нельзя на нем программировать после недели чтения бложиков и относиться к нему, как к языку для анимаций на сайте. Точнее можно. Но в таком случае потом вы будете выглядеть как автор с его постом. Надеюсь, что кроме хейта и wtf люди научатся еще и спрашивать с себя.
Правило-то очень простое — по дефолту функция понимается как FD. FD это Function Declaration, на который, например, применяется hoisting. Так вот по скольку это "declaration" — это является стейтментом. Стейтмент это управляющая конструкция — такая, например, как for/if/throw и так далее. А вот Function Expression это нечто совсем другое. И для того, что из FD сделать FE — надо явно задать контекст — то есть например использовать какой-либо оператор (оператор применяется только и только на expression'ах — поэтому функция понимается как expression и еррора нет).
А уж что вы используете за оператор — () или! или любой другой — не имеет никакой разницы.
Ага, а все потому — что это ни разу не NaN, а простой объект. Разность результатов обьясняется очень просто — это обыкновенный геттер. К тому же выпиленный из стандартов (очередной вопрос к автору — зачем обсуждать что-то, что давно уже официально убрано из даже не языка, а DOM API).
А про глобальный isNaN и Number.isNaN — тоже все очень просто. Глобальный депрекейтед, так как придуман уже милиард лет назад и имеет один косяк — он старается аргумент сначала привести к намберу — и только потом сравнивает.
Естесственно с взрослением языка никто этот глобальный isNaN не использует, кроме как таких "программистов", как автор. Есть вполне давно достпный добропорядочный Number.isNaN который максимально правильно и прозрачно проверяет нан это или нет. И он нам, в принципе, правильно и говорит — это ни разу не NaN.
Понимаю ваше разочарование в такой ситуации — но, тем не менее, язык не виноват. Виноват ваш шеф, который садит почему-то далекого от этого языка человека за поддержку проекта, виноваты возможно клиенты, что торопят со сдачей. Виноваты вы, поскольку у вас юность позади и вы в ней этот язык не выучили (утрирую, но думаю суть понятна).
Но не язык. Конечно проще обвинить JS, а не что-то другое. Но от этого он хуже не станет. Хейтерс гонна хейт )
Ох уж этот юношеский максимализм… Объем памяти в голове сильно ограничен. Некоторые языки позволяют запомнить несколько универсальных правил взаимодействия сущностей языка, и на основе них дальше можно писать любые программы. А другие языки кишат исключениями из этих правил, за которыми постоянно приходится лезть в спеку и тратить на это время.
Возможно вам близок такой подход, мне нет. У технаря должно быть строгое понимание того, что и как он делает. Математика, инжниринг и программирование это не худ. литеретура, где достаточно вдохновится одной книгой и написать похоже другую. Если вам лень или если конкретно у вас ограничен объем того, что можете запомнить — ну это тогда не мои проблемы и не проблемы остальных людей, коих не мало и кто программирует на JS.
Про операторы, нужно или не нужно и так далее и тому подобное — все я это слышал и читал и аргументировал не раз, ибо учитель JS. Но подумайте сами — Java это хорошо для энтерпрайза — ибо у тебя все строго и особой гибкости нет (это в данном случае фича, а не баг). В JS иначе — много флексибилити, много специфик. Трудно, не удобно, не нравится — берешь и программируешь на другом, на том — что нравится. Но какого поливать этот язык грязью я не знаю.
Я могу согласится с некоторыми изьянами языка — например тот же дейт, typeof null, оператор ==. Но это часто совсем не то, за что язык хейтят. Более того это довольно редкие случаи или случаи выбора — никто тебя не обязывает обходит неочевидности ==, просто юзай === и все. Никаких проблем. Но вот такие вот статьи единственное, что оставляют — так ощущение того, что автор просто хотел выплеснуть свою желчь.
Просто статья завалена бредовыми примерами. Вот это вообще какой-то угар:
Типы могут меняться в самых неожиданных местах, что помогает программисту не заснуть во время долгих рабочих ночей:
typeof([1][0])
// number
for(let i in [1]){console.log(typeof(i))}
// string
Начнем с того, что typeof это оператор, поэтому не совсем понятно зачем он там юзает скобки. Ну это косметика, не важно.
Важно то, что в первом случае он делает
typeof 1 // что логично - намбер
Во втором он делает
typeof "0" // так как итерирует над ключами объекта, а первый ключ объекта массива это "0".
Что можно вообще думать о познаниях автора?
Следующий пример не лучше же — сам дергает toString (ну ему это, конечно, не известно, так как зачем читать как работает ==) — и удивляется, что переменная то меняет свое значение.
Если свойство lastIndex больше длины строки, методы test() и exec() завершатся с неудачей, а свойство lastIndex будет установлено в 0.
Кстати, по вашей же ссылке:
Как и при вызове метода exec() (или при совместном с ним вызове), метод test(), вызванный несколько раз на одном и том же экземпляре глобального регулярного выражения, будет начинать проверку с конца предыдущего сопоставления.
Ну если человек искренне считает, что вот эта конструкция в чем-то неправильна:
(1,2,3,4,5,6) === (2,4,6)
То надо не статьи писать бежать, а читать доки про операторы скобок и запятой. И то, что они возвращают последнее выражение.
Это как говорить с Норвежцем и почему-то ожидать, что его слова тебе будут интуитивно понятны.
Я вообще не понимаю, какого рожна в программировании должно быть хотя бы что-то интуитивно понятно? Есть строгие правила — либо ты их знаешь, либо ты не программист. Додумывать своей мудрой головой ничего не надо.
Посмотрел, что это вроде бы как первоапрельская шутка. Ах шутка. Шутка же, ну — че ты?
Так вот, есть одно видео — вроде тоже "шутка" — https://www.destroyallsoftware.com/talks/wat
Тоже про JS в том числе. И я сам знаю массу людей, которые посмотрев такое видео совсем не будут думать так:
Ах это же незатейливая шутка, пойду-ка почитаю спеку и начну понимать!
А будут думать вот так:
Ох е*ать, да я такое гавно даже трогать не буду.
Поэтому это никакая не шутка, а просто безосновательный хейт.
Почему-то автор не решил так пошутить про свой любимый Go.
То ощущение, когда знаешь почему все это так работает, почему в этом есть логика и читаешь очередной высер дегенерата, который не способен почитать спеку или хотя бы постараться разобраться что к чему и ожидает иНтуИтИвНо ЯсНоГо яЗыкА. Тройной фейспалм.
Вот не в моих правилах вообще опускаться на личности и так бомбить, но откуда столько людей с синдромом графомании?
Как им времени своего не жалко только эти статейки калякать.
Отчасти могу с вами согласиться — безусловно существует масса случаев, где можно использовать оба варианта. Но чисто из "правильности" семантики мне все же ближе использование arrow только в качестве каких-то небольших коллбеков. В остальных случаях я использую fe/fd. Причем я не слепо на них сижу, я сперва как и вы — пересел на "arrow везде, где можно", а потом, поняв их смысл и почему они были сделаны все-таки вернулся обратно.
Ну, если вы про скобки, обрамляющие Function Expression, то да, они не обязательны. Но я бы не сказал, что это уж сильно большой недочет, возможно чисто косметический. А вот с delete тут не все здорово, так как delete не удаляет переменные, а удаляет ключи в объекте.
Ну, мне кажется, вы слишком прискребаетесь к формулировке вопросов в подобном "собеседовании". Как бы, наверное, еще правильнее было бы спросить: "объясните разницу спецификаций Function Declaration, Function Expression и Arrow Function Expression", но, как мне кажется, это уже вопрос человеческого понимания и soft skills, нежели самой темы вопроса.
Ну смотрите, я тогда объясню. Сематика лямбд особенная — именно поэтому использовать их абсолютно везде неправильно. Дело в том, что они были созданы именно как функции-помощники, которые не должны полностью представлять все качества функции обычной:
1) Они всегда анонимные.
2) У них нет своего this — и поэтому вы можете смело их использовать/вызывать внутри функций нормальных и не бояться, что контекст этой главной функции подменится контекстом лямбды.
3) У них нет своего arguments — по той же причине, чтобы был прямой и простой доступ к arguments родительской "полноценной" функции.
4) У них более сокращенный синтаксис.
Можно показать это на примере полифила к bind:
// Нам нужно сохранить ссылку на оригинальную функцию, так как если я буду юзать this позже напрямую - то это уже будет this возвращаемой функции - коллбека.
Function.prototype.bind = Function.prototype.bind || function(ctx, ...args) {
const fn = this
return function(...restArgs) {
return fn.apply(ctx, [...args, ...restArgs])
}
}
// Тут this берется от первой "полноценной" функций - можно не переживать, что он подменится на this лямбды.
Function.prototype.bind = Function.prototype.bind || function(ctx, ...args) {
return (...restArgs) => {
return this.apply(ctx, [...args, ...restArgs])
}
}
На самом деле довольно ожидаемый вопрос — так как многие не понимают зачем эти генераторы вообще нужны. На самом деле в большинстве случаев достаточно вместо генератора использовать классический кложур — он так же способен симулировать сохранение состояния в том или ином виде:
function* genNumbersFromOneToTen() {
for (let i = 1; i <= 10; i++) {
yield i
}
}
// По-сути достижимо и просто через
function genNumbersFromOneToTen() {
let i = 1;
const iterator = {
next: function() {
return {
done: i > 10,
value: i++
}
}
}
iterator[Symbol.iterator] = () => iterator
return iterator
}
Но генератор располагает более удобным для этого интерфейсом. Следующие качества, которые делают из генератора совсем не бесполезную фичу:
1) Возможность использовать spread (...) и for-of (по скольку итератор инстанции генератора это он же и есть).
2) Возможность lazy-вычислений — пожалуй это и есть самый главный козырь генераторов — вы можете засунуть туда сложный синхронный алгоритм, который можете спокойно ставить на паузу где вам угодно и "заводить" опять по мере необходимости. Более того, с помощью next() вы можете прокидывать новые данные внутрь уже работающего генератора.
3) Около-асинхронные трюки: по скольку генератор эффективно останавливает даже синхронный код в любой его точке исполнения — вы можете смело делать обертки-генераторы вокруг более сложных и времязатратных синхронных операций — и с помощью того же yield выходить на определенное время из работы — дабы дать остальным таскам, ожидающим в event-queue запуститься. То есть, иными словами, вы относительно безболезненно можете разбить сложную синхронную операцию на более мелкие — и эти мелкие запускать асинхронно — для того, чтобы браузер, например, не фризанул при каком-то сложном алгоритме.
По-скольку ruvds скорее всего все равно до качества статей, то всем новичкам, читающим статью хочу сказать, что здесь есть достаточное количество вредных советов, чтобы к этой статье относиться несерьезно.
Использовать "когда хочу" — это значит не понимать зачем вообще лямбды были придуманы. Отличий от обычной функции более, чем достаточно. И да — существуют вполне ясные и понятные причины почему в том или ином случае нужно использовать именно то или другое.
Больше 10 лет в вебе, даже и не понял что за аббревиатура такая. Лучше писать нормальное название, тогда все сразу понятно.
Это общепринятное сокращение, которое используется уже много-много лет. Либо вы не особо в JS, либо вы не читаете материал, третьего представить не могу.
За такие вопросы я готов убивать.
Воу-воу, попридержите коней. Вполне нормальная постановка вопроса.
Ну, пожалуй, определенную поверхностную картину такие бенчмарки, конечно, могут дать. Но надо держать в голове всегда, что это достаточно не точные тесты.
Все гораздо проще, чем вы думаете. Не надо юзать бенчмарки на jsperf, надо смотреть проблемные места конкретного приложения. В конкретном месте с конкретными условиями — и сразу все становится понятно, где и что надо оптимизировать. Профайлер в devtools показывает все очень наглядно.
Насчет benchmark.js, я, если честно, не помню, но там, на сколько я помню, суть не только в тестировщике, а скорее в самих тестах.
Прислушиваться к определенным техникам есть смысл, но не очень большой, если честно. Так как от релиза к релизу (v8) все это оптимизируется и выполняется по разному.
Автор, у вас из поста в пост какой-то негатив и полное отчаяние. Может быть вам просто не стоит программировать? В этой профессии есть столько всего интересного и крутого, а у вас — в одном посте про выгорание на неинтересном аджайле, в другом — про то как кто-то там умнее.
Как-то это все навевает скорее художественный роман с личными переживаниями и муками. Не понимаю зачем эти статьи.