Pull to refresh
-15
0

User

Send message
Разбор такого кода, по мнению автора статьи, поможет всем желающим лучше разобраться в JavaScript, в очень странном, но многими любимом языке.

https://habr.com/ru/company/ruvds/blog/499670/#comment_21560988

Запрыгивайте на эту волну хайпа! Я и вправду впечатлен Deno. После двух лет разработки и долгого пути к успеху новая среда выполнения JavaScript выглядит просто великолепно, и мне не терпится начать экспериментировать с ней. Node появился около 11 лет назад и стал новой вехой в истории JavaScript. Он сделал язык лучше, и я думаю, что мы достигли нового рубежа, пришло время Deno!

Покупай — налетай, арбуз сочный, сладкий! Падхади, дорогой, пакупай — сладкие, как мед, гладкие, как девушка! Налетай, расхватывай! Подходи народ, свой огород! половина — сахар, половина — мед!


А вообще — нет.

Так а разве это всегда возможно? Ну, то есть, некоторые ошибки можно вычислить, но их не просто пофиксить автоматически.

Приятно поболтать со знающими программистами, vitaliy2 & faiwer. Если хотите, добавляйтесь в телегу: @mwhyte.

Речь по "случайные" глобалы, а не про вообще любые. Фича настолько не выдержала проверку временем что её экстренно залатали.

Я не совсем понимаю, что такое "случайные глобалы". Единственное, что могу к этому ассоциировать, так это что-то типа:


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 люди научатся еще и спрашивать с себя.

При все при этом — потоки тоже есть. Причем сейчас даже не нужно и симулировать подпроцессами, достаточно require('worker_threads').

О каком обмане идет речь?


Правило-то очень простое — по дефолту функция понимается как FD. FD это Function Declaration, на который, например, применяется hoisting. Так вот по скольку это "declaration" — это является стейтментом. Стейтмент это управляющая конструкция — такая, например, как for/if/throw и так далее. А вот Function Expression это нечто совсем другое. И для того, что из FD сделать FE — надо явно задать контекст — то есть например использовать какой-либо оператор (оператор применяется только и только на expression'ах — поэтому функция понимается как expression и еррора нет).


А уж что вы используете за оператор — () или! или любой другой — не имеет никакой разницы.

Вот именно, тем более это к JS вообще не имеет никакого отношения, а, если уж на то пошло, к стандарту IEEE-754.

Ага, а все потому — что это ни разу не 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 (ну ему это, конечно, не известно, так как зачем читать как работает ==) — и удивляется, что переменная то меняет свое значение.

https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/RegExp/lastIndex


Если свойство lastIndex больше длины строки, методы test() и exec() завершатся с неудачей, а свойство lastIndex будет установлено в 0.

Кстати, по вашей же ссылке:


Как и при вызове метода exec() (или при совместном с ним вызове), метод test(), вызванный несколько раз на одном и том же экземпляре глобального регулярного выражения, будет начинать проверку с конца предыдущего сопоставления.

Ну если человек искренне считает, что вот эта конструкция в чем-то неправильна:


(1,2,3,4,5,6) === (2,4,6)

То надо не статьи писать бежать, а читать доки про операторы скобок и запятой. И то, что они возвращают последнее выражение.


Это как говорить с Норвежцем и почему-то ожидать, что его слова тебе будут интуитивно понятны.


Я вообще не понимаю, какого рожна в программировании должно быть хотя бы что-то интуитивно понятно? Есть строгие правила — либо ты их знаешь, либо ты не программист. Додумывать своей мудрой головой ничего не надо.

Посмотрел, что это вроде бы как первоапрельская шутка. Ах шутка. Шутка же, ну — че ты?


Так вот, есть одно видео — вроде тоже "шутка" — https://www.destroyallsoftware.com/talks/wat
Тоже про JS в том числе. И я сам знаю массу людей, которые посмотрев такое видео совсем не будут думать так:


Ах это же незатейливая шутка, пойду-ка почитаю спеку и начну понимать!

А будут думать вот так:


Ох е*ать, да я такое гавно даже трогать не буду.

Поэтому это никакая не шутка, а просто безосновательный хейт.
Почему-то автор не решил так пошутить про свой любимый Go.

То ощущение, когда знаешь почему все это так работает, почему в этом есть логика и читаешь очередной высер дегенерата, который не способен почитать спеку или хотя бы постараться разобраться что к чему и ожидает иНтуИтИвНо ЯсНоГо яЗыкА. Тройной фейспалм.


Вот не в моих правилах вообще опускаться на личности и так бомбить, но откуда столько людей с синдромом графомании?


Как им времени своего не жалко только эти статейки калякать.


// я понимаю, что это перевод

Верно, функция является объектом, а любой объект транслируется в true при переводе.


!!function(){} === true

Может быть вам поможет что-то типа:


function pipe() {
    return [...arguments].reduce((value, fn) => fn(value))
}
function double(value) {
    return value * 2
}
function plus10(value) {
    return value + 10
}

const value = 42
pipe(42, double, plus10)

Отчасти могу с вами согласиться — безусловно существует масса случаев, где можно использовать оба варианта. Но чисто из "правильности" семантики мне все же ближе использование arrow только в качестве каких-то небольших коллбеков. В остальных случаях я использую fe/fd. Причем я не слепо на них сижу, я сперва как и вы — пересел на "arrow везде, где можно", а потом, поняв их смысл и почему они были сделаны все-таки вернулся обратно.

Information

Rating
Does not participate
Registered
Activity