Все єто совершенно бесполезная игрушка, смысла в которой не больше джаст фор фан, по причине того, что любое из "приложений" разрушит работу системы без какой либо возможности системы воспрепятствовать єтому.
Одновременно с єтим, переход на архитектуру 386 меняет ситуацию, и одновременно с єтим делает не менее бесполезным заявленным код, только уже по другой причине - в архитектуре которая предоставляет подход, к решению фундаментальных проблем многозадачности, даже на ее уровне кооперативной, нужно применять другие машинерии, опирающиеся на архитектуру того же самого 386
JavaScript больше страдает не от своих особенностей архитектуры, которых полно и в других языках, но вот от подобных материалов, где вместо того, чтобы развеять сложившиеся мифы, создаются новые.
Ниже я разберу тезисы материала, покажу что почти каждый из них несостоятелен и говорит скорее о том, о чем сказал Дуглас Крокфорд еще в далеком 2000 году:
JavaScript:The World's Most Misunderstood Programming Language
Судите сами:
"JavaScript отстой, потому что '0' == 0
JavaScript это скриптовый язык программирования. Для этой группы зяыков, подобное поведение является нормой и продиктовано оно теми целями ради которых язык был предназначен. Выше на это уже обратили внимание. Как и на то, что язык развивается и предоставляет альтернативные механизмы решения подобных задач.
eval хуже, чем вы думаете:
Это прекрасная иллюстрация того, как не знание норм языка заставляет делать ошибочные выводы.
Для того, чтобы понять поведение eval нужно понимать следующие его(JS) нормы:
Это динамический интерпретируемый язык, что за исключением правил Static Semantics диктует правила интерпретации любого его statement именно в момент его интерпретации. То есть Агент исполняющий код - понятия не имеет до начала интерпретации конкретного statement что с ним делать. То есть для интерпретатора все что перед вами это набор идентефикаторов поведение которых связывается с определенным алгоритмом именно в момент интерпретации.
Для любого Агента - не существует никакой функции eval math console и так далее. Это все идентификаторы которые ссылаются на что-то. И что делать с этим что-то, можно понять только в конкретный момент интерпретации.
eval это всего лишь property от Global Object. Который может быть связан с чем угодно.
конструкция вида identifier() интерпретируется агентом как Callable Expression. Агент ничего не знает о идентификаторе. Как следствие код вида: eval(';'); ничего для еганта не означает кроме того, что перед ним выражение которое нужно разбить на части, получить результаты выполнения каждой из них и подставить их в связанный алгоритм.
До появления "strict mode", eval был связан с поведением, которое описывалось как стандартное выполнение кода в глобальном окружении. С появлением "strict mode", super statement в спецификацию добавили поведение в описания алгоритма работы функционального обьекта, где в случае использования eval для инициализации окружения заданного кода - требуется брать не глобальное окружение, но окружение где напрямую eval был задекларирован.
А теперь собираем все в кучу:
eval - это обычный идентификатор который для агента, сам по себе, ничего не означает. Просто набор символов который интерпретируется как Reference Expression. Даже без какой либо проверки на то существует ли вообще такой Reference.
С появлением strict mode и super поведение Regular Function было изменено, что потребовало изменения ИМЕННО АЛГОРИТМА самого Callable Expression и как следствие внесение правок в поведение eval.
Сравнить просто ссылку на функциональный обьект описывающий eval с ссылкой внутри любого другого идентификатора (то что автор назвал переименованием) просто так нельзя. По причине существование super() который НЕ является вызовом функции, но является особым специфическим поведением, в отличии от eval который является типичным expression.
Добавте к этому тот факт, что способов вызвать функциональный обьект в JS больше 14 разных штук. И каждый из них должен быть учтен в связи с новым поведением strict super etc, что в случае с eval смерти подобно, так как это фундаментальная часть языка.
Я постарался очень сжато описать функционал того чем является eval. Деталей и ньюансов его реализации масса. Как следствие это не eval странный - это автор не понимает как он работает.
Циклы в JS делают вид, что их переменные захватываются по значению
В JavaScript ничего не делается по значению если в спецификации не указано явным образом обратное.
Algorithm steps may declare named aliases for any value using the form “Let x be someValue”. These aliases are reference-like in that both x and someValue refer to the same underlying data and modifications to either are visible to both. Algorithm steps that want to avoid this reference-like behaviour should explicitly make a copy of the right-hand side: “Let x be a copy of someValue” creates a shallow copy of someValue.
Как только это становится очевидным, то и eval уже не такой странный и for statement оказывается работает более чем логично.
Тот самый "ложный" объект
Общепринято считать, что в JavaScript есть 8 ложных (falsy) значений: false, +0, -0, NaN, "", null, undefined и 0n
Это общепринятое заблуждение. Потому, что в JS нет универсальных правил разрешения типов. И то, как именно происходит разрешение конкретного типа, зависит от связанного с текущим интерпретируемым выражением с которым связан алгоритм спецификации.
То что Вы привели как falsy - это поведение абстрактной операции toBolean, которая не обязательна для вызова при любых типах сравнения.
Далее, ваша претензия [[IsHTMLDDA]] не верна по сути, потому, что она описана в спецификации HTML5 и второе - использовать этот механизм может любой External Object а не только document.all.
Ну и наконец вот Вам пара примеров для размышления
Это не falsy значения, или странные обьекты. Это не знание фундаментального принципа заложенного в JS с момента еге первой спецификации. Очень рекомендую к ознакомлению главы о том что такое Object в JS и что такое Exotic Object
Графемы и перебор строк
Тут вообще сплошная ваша. Разложим по полочкам:
Человек оценивая длину строки, ожидает увидеть количество ОТОБРАЖАЕМЫХ символов
Эволюция произвела десятки разных способов формирования такого символа ( латиница, иероглифиы, арабская вязь и т.д.) где способы формирования такого символа не укаладываются в схему: таблица где каждому коду соотвествует один знак
unicode это стандарт, который попытался унифицировать эту работу. Обьем документации по этому стандарту больше чем весь JS вместе взятый
Есть стандарт unicode (описывающий способы формирования символа) а есть способ кодирования этого способа. UTF8, UTF16, UTF32 - это способы кодирования где 8,16,32 обозначатает количество используемых бит на реализацию нашей задачи.
В зависимости от того, какое кодирование мы используем, один и тот же символ может кодироваться разной последовательностью байт. То есть один и тот же символ может быть закодирован как одним байтом, двумя, тремя и так далее. И все это может происходит в рамках одной и той же системы кодирования. Например: один и тот же символ представлен разной последовательностью кодирования
`Á`.length; // 1
`A\u0301`; // 2
и оба эти символа с точки зрения Unicode идентичны. Это А с ударением.
Стандарт Unicode пытается описать все возможные комбинации подобных поведений. Кодирование - пытается закодировать все это в рамках выданных бит. В результате чего представление символа может занимать последовательность байт.
JS реализует систему кодирования UTF16.
Возможности языка JS позволяют как адресовать конкретный байт в строке, так и разбирать его по два байта на один управляющий символ. Потому
Так как Exotic Object String - для метода length реализует алгоритм, где подсчитывается простое колличества байт на кодирование UTF16 то для '😀' мы видим ответ 2; В то же создавая Exotic Object Array мы используем spread, который вызывает Iterator у Object String который в свою очередь использует не побайтовую адресацию, но преобразование CodePointAt который итерируетсся уже по UTF16 кодированным символам (парам или нет - не важно). При этом разбирая строку именно по CodePoint кодированию стандарта. Но не по представлению символа. То есть если у нас будет представление которое потребует больше 16 бит, итератор разобьет это на два проперти.
Теперь мы должны понимать, что привычные операции существующие в JS считают либо сырые байты, либо CodePoint. Чего совершенно недостаточно для того чтобы получить ожидаемый результат для человека - сколько вижу столько и считаю.
Выход из этой ситуации - это либо самостоятельная реалиация станадрта Unicode со всеми его 900 страниц спецификации, либо использование регулярных выражений с ключем /u для максимальной поддержки старых браузеров или ключем /v для того чтобы получить максимальный комфорт с работой со строками с поддержкой ВСЕХ символьных классов стандарта Unicode.
Разрежённые массивы
В JS то что вы создается при помощи литерала [] или конструктора Array называется Exotic Object Array. Это не Array в том смысле как это может быть в других языках. Это обьект с особым поведением.
Только типизированные массивы ведут себя именно как привычные массивы.
Что такое Exotic Object я давал ссылку раньше.
Вместо ИГОГО
О точке с запятой. Правило - ставте точку с запятой всегда написано кровью. Тут действительно можно ругать язык за то, что в нем существует алгоритм автоматической простановки.
Всё, что связано с == и !=
Ничего странного в них нет, если читать спецификацию, а не прибывать в иллюзиях вида: приведение типов и так далее
Всё, что связано с this
Реализуется простой блок схемой. Если максимально упростить - то все что нужно знать так это, что все в JS это ссылочныее типы (Reference Like термин спецификации) и что this это просто скрытый параметр для вызова Regular Function. Установка которого зависит от формы callable expression
NaN не равен ничему, даже самому себе
+0 против -0
Ошибки из-за плавающей точности (IEEE 754)
Это все функционирует в рамках стандарта IEE754 и абсолютно идентично другим языкам программирования которые реализуют этот стандарт. Например C Pascal Fort и так далее. То есть утверждение автора ложно. Никаких особенностей там нет. Есть не знание языка или стандарта.
typeof null - это "object"
Это абсолютно нормальное поведение описанное в первой же версии спецификации. Никакой ошибки тут нет, о чем говорил как сам Эйк так и многие другие. Была архитектурная ошибка допустившая существование null и undefined в языке где с самого начала в этом необходимости не было. Тем не менее главное - это описанное спецификацией с его первой версии поведение. Для меня логичное.
Особенности работы без строгого режима и использование var
Возврат примитивных значений из конструкторов
и т.д. и т.п.
это не знание фундаментальных особенностей языка, которые являются его архитектурой.
Очень плохо когда материал такого рода, вместо того чтобы заниматься ликбезом, множит невежество.
Статья не имеет никакого отношения к внутреннему устройству языка JavaScript. Статья описывает одну из возможностей его реализации.
Например, для работы JavaScript согласно его спецификации не нужен call stack. Он там вообще никаким образом не описывается. Работа и вызов функций происходит без необходимости что-то класть в стек.
Или цикл событий, который является одним ИЗ способов реализации работы с агентом выполняющим JavaScript код. Опять же спецификации языка глубоко плевать на то, каким образом вы будете помещать в Job Queue задачи на выполнения.
Представьте на секунду, что Agent исполняющий JS код, автоматически научился распределять нагрузку на все доступные потоки.
Код Мартина будет оптимизирован автоматически. Менять ничего не нужно будет. Вычисление простого числа воспользуется всеми доступными ресурсами многопроцессорной архитектуры.
Код на 16 строк, все так же будет работать в одном потоке. И оптимизировать его сможет только человек.
Если бы я попросил кандидата решить подобную задачу и в ответ получил бы такие шестьдесят строк, то кандидат не прошёл бы собеседование.
Если бы Вы проходили у меня собеседование, то Ваш код на 16 строчек, был бы завернут на первой же строке. const primes: number[] = [];
Сравните эту же строку с кодом Мартина. И попробуйте пояснить почему Вас бы сразу завернули.
Потому, что он говорит о Вашем не знании того как работает JS изнутри. В то же время код Мартина, заставил бы меня задать несколько уточняющих вопросов и продолжить собеседование.
Мне кажется, что Вы не поняли главное о чем писал дядя Боб. Он не давал Вам рецептов. Он прививал культуру мышления. Ваш код в 16 строчек - выполняет свою задачу. Он прекрасно может быть использован для решения на коленке. Но он безобразен. Безобразен хотя бы потому, что не оставляет никаких шансов современным оптимизаторам что-то с этим кодом сделать.
В тоже время код от Мартина такие возможности дает. И если инструмент способен делать подобные оптимизации - он с кодом Мартина может сделать много чего полезного и интересного. А с кодом в 16 строк - почти ничего.
При холодром старте, подготовка js кода может занимать больше 100% времени используемошо на его исполнение. Специфика языка.
Как следствие - кеширование как минимум, а способность управлять тем что и как кешируется/компилируется - как максимум, один из золотых граалей старта приложения.
Мне показалось, что Вы не поняли автора. Автор говорил о том, что программисты JS кода, до конца не понимают как использовать инструмент, которы! они используют.
Инструмент, потенциал которого, в силу общей слабости JS комьюнити, до сих пор не раскрыт и имеет большой потенциал. С чем лично я, более чем согласен.
abortController - никакого отношения к JS не имеет. Єто api которое может предоставить host среда. А может и не предоставить, в отличии от того что она обязана предоставить для исполнения js кода согласно спецификации.
Работать постоянно и исключительно в одной только ОС Linux/*BSD у вас скорее всего не получится (без ухода в религиозный фанатизм) и пусть лишь ради 5% работы, но придется переключаться в Windows или использовать виртуализацию.
Как же 500 самых быстрых компьютеров мира перегружают или виртуализруют виндовз?
Наверное я религиозный фанатик, которому linux более чем достаточно в решении его повседневных задач.
Мне кажется, что перевод требует существенных уточнений.
Например: зачем автор переводит термины на русский язык, в случаях когда нет устоявшейся терминологии? abrupt в спецификации, или в обиходе используется именно как abrupt, но не как внезапный.
Другой пример:
Если argument - внезапный (abrupt), вернуть argument.
формулировка вернуть argument может сбивать столку. Какой аргумент? Куда вернуть? Из complition record?
На самом деле єто следовало бы перевести с акцентом на то, что происходит полноценный return из метода, с пробросом complition record вверх по стеку вызова методов.
Весь тест можно выкинуть в топку по одной простой причине: google выделяет разное колличество ресурсов для индексации того или иного домена. Называется краулинговый бюджет. Который прямо влияет в том числе на обьем работы совершаемой гуглом для индексации контента.
Чтобы тест стал корректным - следовало завести тестовый домен, о котором google ничего не знал ранее, а еще лучше хотябы 100.
И если бы авторы єто сделали, то обнаружили бы что мифы уже не такие и мифы.
Самый простой опыт - єто домен с контентом генерируемым на стороне клиента и такой-же в статике. Внезапно оказывается, что скорость индексации сравниваемых доменов отличается в разы.
Из материала, может сложиться ложное впечатление, будто бы typedArray играют какую-то важную роль в производительности всей задачи. Что может спровоцировать читателя в будущем использовать их вместо типичного ExoticObjectArray.
Вероятно, для информативности, следовало бы добавить, что любые typed array в js только тогда приобретают "мистические" черты супер-производительности, когда такие array можно передавать в неизменном виде в какое либо внешнее API. Например imageData от canvas.
Все же прочее, что делается с темже тайпедАррай, в современных агентах, подобных v8, работает с тойже производительностью. При єтом может быть причиной ее просадки именно в момент формарования отображения тайпед аррай на типичный js код.
То есть условный консоле.лог, примененрый к тайпед аррай, может привести к худшей производительности чем он же к exotic object array.
1) web assembly не может быть быстрее js кода хотябы потому, что абстрактный wasm исполняется ровно тойже виртуальрой машиной что и абстрактный байткод, в который собирается в v8 js код.
wasm может быть более предсказуемым в случае, когда мы сталкиваемся с гарбаж коллектором и типизацией, чего в озвученном выше примере нет от слова совсем. GC задействован минимально. Типизация работает ровно также как в wasm typedArray.
2) простое копирование буфера в канвас, для случаев typedArray на порядок быстрее аналога в webGl. уже хотябы потому, что нет издержек на обслуживание каждого пикселя. webGl дал бы Вам прирост тогда, когда вы бы положили на gpu ваши условрые треугольники позволив gpu их красить самостоятельно. в примере выше обслуживается каждый пиксель отдельно. и тут не может быть ничего быстрее копирования буфера.
xms сам по себе никак не мог повлиять на запуск игр. от слова совсем.
исключение, если он отьедал памяти в первом 1024 сегменте столько, что остатка не хватало для запуска приложения. только тогда єто не проблема xms, а проблема доступной памяти в текущем окружении, крторую можно было решать исключая любые други приложерия.
к слову сказать. xms появился как способ дать временное окно перехода между dos и реал моде к виндовс и протектед моде. Дать апи, которое бы позволило запускать приложения в новой среде с минимальными издержками.
Дело в том, что уже с появления 286 процессора стало известно, как адресовать память выше 1мб без использования прослоек типа himem.sys. Единственным недостатком которого, являлась полная несовместимость реал мод,рс протектед мод. Но полностью прозрачный механизм адресации памяти.
Майкрасовт и прочих игроков рынка єто не сильно устраивало именно потому, что нужно было обеспечить бесшовныи переход с дос на виндовс.
В результате появляются франкинштейны вроде xms которые, по сути спекулируют на томже механизме, но предоставляя уровень абстракции єффектинвно заменяемый в новом окружении.
Все єто совершенно бесполезная игрушка, смысла в которой не больше джаст фор фан, по причине того, что любое из "приложений" разрушит работу системы без какой либо возможности системы воспрепятствовать єтому.
Одновременно с єтим, переход на архитектуру 386 меняет ситуацию, и одновременно с єтим делает не менее бесполезным заявленным код, только уже по другой причине - в архитектуре которая предоставляет подход, к решению фундаментальных проблем многозадачности, даже на ее уровне кооперативной, нужно применять другие машинерии, опирающиеся на архитектуру того же самого 386
JavaScript больше страдает не от своих особенностей архитектуры, которых полно и в других языках, но вот от подобных материалов, где вместо того, чтобы развеять сложившиеся мифы, создаются новые.
Ниже я разберу тезисы материала, покажу что почти каждый из них несостоятелен и говорит скорее о том, о чем сказал Дуглас Крокфорд еще в далеком 2000 году:
Судите сами:
JavaScript это скриптовый язык программирования. Для этой группы зяыков, подобное поведение является нормой и продиктовано оно теми целями ради которых язык был предназначен. Выше на это уже обратили внимание. Как и на то, что язык развивается и предоставляет альтернативные механизмы решения подобных задач.
eval хуже, чем вы думаете:
Это прекрасная иллюстрация того, как не знание норм языка заставляет делать ошибочные выводы.
Для того, чтобы понять поведение eval нужно понимать следующие его(JS) нормы:
Это динамический интерпретируемый язык, что за исключением правил Static Semantics диктует правила интерпретации любого его statement именно в момент его интерпретации. То есть Агент исполняющий код - понятия не имеет до начала интерпретации конкретного statement что с ним делать. То есть для интерпретатора все что перед вами это набор идентефикаторов поведение которых связывается с определенным алгоритмом именно в момент интерпретации.
Для любого Агента - не существует никакой функции eval math console и так далее. Это все идентификаторы которые ссылаются на что-то. И что делать с этим что-то, можно понять только в конкретный момент интерпретации.
eval это всего лишь property от Global Object. Который может быть связан с чем угодно.
конструкция вида identifier() интерпретируется агентом как Callable Expression. Агент ничего не знает о идентификаторе. Как следствие код вида:
eval(';')
; ничего для еганта не означает кроме того, что перед ним выражение которое нужно разбить на части, получить результаты выполнения каждой из них и подставить их в связанный алгоритм.До появления "strict mode", eval был связан с поведением, которое описывалось как стандартное выполнение кода в глобальном окружении. С появлением "strict mode", super statement в спецификацию добавили поведение в описания алгоритма работы функционального обьекта, где в случае использования eval для инициализации окружения заданного кода - требуется брать не глобальное окружение, но окружение где напрямую eval был задекларирован.
А теперь собираем все в кучу:
eval - это обычный идентификатор который для агента, сам по себе, ничего не означает. Просто набор символов который интерпретируется как Reference Expression. Даже без какой либо проверки на то существует ли вообще такой Reference.
С появлением strict mode и super поведение Regular Function было изменено, что потребовало изменения ИМЕННО АЛГОРИТМА самого Callable Expression и как следствие внесение правок в поведение eval.
Сравнить просто ссылку на функциональный обьект описывающий eval с ссылкой внутри любого другого идентификатора (то что автор назвал переименованием) просто так нельзя. По причине существование super() который НЕ является вызовом функции, но является особым специфическим поведением, в отличии от eval который является типичным expression.
Добавте к этому тот факт, что способов вызвать функциональный обьект в JS больше 14 разных штук. И каждый из них должен быть учтен в связи с новым поведением strict super etc, что в случае с eval смерти подобно, так как это фундаментальная часть языка.
Я постарался очень сжато описать функционал того чем является eval. Деталей и ньюансов его реализации масса. Как следствие это не eval странный - это автор не понимает как он работает.
Циклы в JS делают вид, что их переменные захватываются по значению
В JavaScript ничего не делается по значению если в спецификации не указано явным образом обратное.
Как только это становится очевидным, то и eval уже не такой странный и for statement оказывается работает более чем логично.
Тот самый "ложный" объект
Это общепринятое заблуждение. Потому, что в JS нет универсальных правил разрешения типов. И то, как именно происходит разрешение конкретного типа, зависит от связанного с текущим интерпретируемым выражением с которым связан алгоритм спецификации.
То что Вы привели как falsy - это поведение абстрактной операции toBolean, которая не обязательна для вызова при любых типах сравнения.
Далее, ваша претензия [[IsHTMLDDA]] не верна по сути, потому, что она описана в спецификации HTML5 и второе - использовать этот механизм может любой External Object а не только document.all.
Ну и наконец вот Вам пара примеров для размышления
Это не falsy значения, или странные обьекты. Это не знание фундаментального принципа заложенного в JS с момента еге первой спецификации. Очень рекомендую к ознакомлению главы о том что такое Object в JS и что такое Exotic Object
Графемы и перебор строк
Тут вообще сплошная ваша. Разложим по полочкам:
Человек оценивая длину строки, ожидает увидеть количество ОТОБРАЖАЕМЫХ символов
Эволюция произвела десятки разных способов формирования такого символа ( латиница, иероглифиы, арабская вязь и т.д.) где способы формирования такого символа не укаладываются в схему: таблица где каждому коду соотвествует один знак
unicode это стандарт, который попытался унифицировать эту работу. Обьем документации по этому стандарту больше чем весь JS вместе взятый
Есть стандарт unicode (описывающий способы формирования символа) а есть способ кодирования этого способа. UTF8, UTF16, UTF32 - это способы кодирования где 8,16,32 обозначатает количество используемых бит на реализацию нашей задачи.
В зависимости от того, какое кодирование мы используем, один и тот же символ может кодироваться разной последовательностью байт. То есть один и тот же символ может быть закодирован как одним байтом, двумя, тремя и так далее. И все это может происходит в рамках одной и той же системы кодирования. Например: один и тот же символ представлен разной последовательностью кодирования
и оба эти символа с точки зрения Unicode идентичны. Это А с ударением.
Стандарт Unicode пытается описать все возможные комбинации подобных поведений. Кодирование - пытается закодировать все это в рамках выданных бит. В результате чего представление символа может занимать последовательность байт.
JS реализует систему кодирования UTF16.
Возможности языка JS позволяют как адресовать конкретный байт в строке, так и разбирать его по два байта на один управляющий символ.
Потому
Так как Exotic Object String - для метода length реализует алгоритм, где подсчитывается простое колличества байт на кодирование UTF16 то для '😀' мы видим ответ 2;
В то же создавая Exotic Object Array мы используем spread, который вызывает Iterator у Object String который в свою очередь использует не побайтовую адресацию, но преобразование CodePointAt который итерируетсся уже по UTF16 кодированным символам (парам или нет - не важно).
При этом разбирая строку именно по CodePoint кодированию стандарта. Но не по представлению символа. То есть если у нас будет представление которое потребует больше 16 бит, итератор разобьет это на два проперти.
Теперь мы должны понимать, что привычные операции существующие в JS считают либо сырые байты, либо CodePoint. Чего совершенно недостаточно для того чтобы получить ожидаемый результат для человека - сколько вижу столько и считаю.
Выход из этой ситуации - это либо самостоятельная реалиация станадрта Unicode со всеми его 900 страниц спецификации, либо использование регулярных выражений с ключем /u для максимальной поддержки старых браузеров или ключем /v для того чтобы получить максимальный комфорт с работой со строками с поддержкой ВСЕХ символьных классов стандарта Unicode.
Разрежённые массивы
В JS то что вы создается при помощи литерала [] или конструктора Array называется Exotic Object Array. Это не Array в том смысле как это может быть в других языках. Это обьект с особым поведением.
Только типизированные массивы ведут себя именно как привычные массивы.
Что такое Exotic Object я давал ссылку раньше.
Вместо ИГОГО
О точке с запятой. Правило - ставте точку с запятой всегда написано кровью. Тут действительно можно ругать язык за то, что в нем существует алгоритм автоматической простановки.
Ничего странного в них нет, если читать спецификацию, а не прибывать в иллюзиях вида: приведение типов и так далее
Реализуется простой блок схемой. Если максимально упростить - то все что нужно знать так это, что все в JS это ссылочныее типы (Reference Like термин спецификации) и что this это просто скрытый параметр для вызова Regular Function. Установка которого зависит от формы callable expression
Это все функционирует в рамках стандарта IEE754 и абсолютно идентично другим языкам программирования которые реализуют этот стандарт. Например C Pascal Fort и так далее.
То есть утверждение автора ложно. Никаких особенностей там нет. Есть не знание языка или стандарта.
Это абсолютно нормальное поведение описанное в первой же версии спецификации. Никакой ошибки тут нет, о чем говорил как сам Эйк так и многие другие. Была архитектурная ошибка допустившая существование null и undefined в языке где с самого начала в этом необходимости не было.
Тем не менее главное - это описанное спецификацией с его первой версии поведение. Для меня логичное.
это не знание фундаментальных особенностей языка, которые являются его архитектурой.
Очень плохо когда материал такого рода, вместо того чтобы заниматься ликбезом, множит невежество.
Если код, способен модифицировать /etc то єто означает что у него есть рут.
После монимания єтого момента чтения материала теряет всяческий смысл. Даже если настроен SELinux.
Код описаный в статье - єто детская подделка на коленке, развитость которой на уровне 1998 года.
Статья не имеет никакого отношения к внутреннему устройству языка JavaScript.
Статья описывает одну из возможностей его реализации.
Например, для работы JavaScript согласно его спецификации не нужен call stack. Он там вообще никаким образом не описывается. Работа и вызов функций происходит без необходимости что-то класть в стек.
Или цикл событий, который является одним ИЗ способов реализации работы с агентом выполняющим JavaScript код. Опять же спецификации языка глубоко плевать на то, каким образом вы будете помещать в Job Queue задачи на выполнения.
Представьте на секунду, что Agent исполняющий JS код, автоматически научился распределять нагрузку на все доступные потоки.
Код Мартина будет оптимизирован автоматически. Менять ничего не нужно будет. Вычисление простого числа воспользуется всеми доступными ресурсами многопроцессорной архитектуры.
Код на 16 строк, все так же будет работать в одном потоке. И оптимизировать его сможет только человек.
Это Вам как самый показательный пример.
Если бы Вы проходили у меня собеседование, то Ваш код на 16 строчек, был бы завернут на первой же строке.
const primes: number[] = [];
Сравните эту же строку с кодом Мартина. И попробуйте пояснить почему Вас бы сразу завернули.
Потому, что он говорит о Вашем не знании того как работает JS изнутри.
В то же время код Мартина, заставил бы меня задать несколько уточняющих вопросов и продолжить собеседование.
Мне кажется, что Вы не поняли главное о чем писал дядя Боб. Он не давал Вам рецептов. Он прививал культуру мышления. Ваш код в 16 строчек - выполняет свою задачу. Он прекрасно может быть использован для решения на коленке. Но он безобразен. Безобразен хотя бы потому, что не оставляет никаких шансов современным оптимизаторам что-то с этим кодом сделать.
В тоже время код от Мартина такие возможности дает. И если инструмент способен делать подобные оптимизации - он с кодом Мартина может сделать много чего полезного и интересного. А с кодом в 16 строк - почти ничего.
Єто ошибка потому, что выбрав оптимальную архитектуру, вы, как человек который не знает систему, так и не поймете почему она тормозит.
А тормозить она будет из-за невозможности оптимизировать ваш код Агентом, который пришел в восхищение от вашей архитектуры и читаемости кода.
При холодром старте, подготовка js кода может занимать больше 100% времени используемошо на его исполнение. Специфика языка.
Как следствие - кеширование как минимум, а способность управлять тем что и как кешируется/компилируется - как максимум, один из золотых граалей старта приложения.
Мне показалось, что Вы не поняли автора. Автор говорил о том, что программисты JS кода, до конца не понимают как использовать инструмент, которы! они используют.
Инструмент, потенциал которого, в силу общей слабости JS комьюнити, до сих пор не раскрыт и имеет большой потенциал. С чем лично я, более чем согласен.
Лекции Константина Анохина, действующего нейробиолога, о том что мы сейчас знаем про память. Минимум 10 летней давности.
Рассказывают намного подробнее. В том числе утверждается о существовании єксперемнтальных препаратов радикально меняющих процесс запоминания.
abortController - никакого отношения к JS не имеет. Єто api которое может предоставить host среда. А может и не предоставить, в отличии от того что она обязана предоставить для исполнения js кода согласно спецификации.
а если опыт 30 лет, то кто тогда?
а мне нравится. я бы даже специально заплатил чтобы такое сделали. мне кажется сочно.
Как же 500 самых быстрых компьютеров мира перегружают или виртуализруют виндовз?
Наверное я религиозный фанатик, которому linux более чем достаточно в решении его повседневных задач.
Мне кажется, что перевод требует существенных уточнений.
Например: зачем автор переводит термины на русский язык, в случаях когда нет устоявшейся терминологии? abrupt в спецификации, или в обиходе используется именно как abrupt, но не как внезапный.
Другой пример:
формулировка вернуть argument может сбивать столку. Какой аргумент? Куда вернуть? Из complition record?
На самом деле єто следовало бы перевести с акцентом на то, что происходит полноценный return из метода, с пробросом complition record вверх по стеку вызова методов.
И так далее.
А еще можно познакомиться с cache api и использовать его, с 100% гарантией.
Весь тест можно выкинуть в топку по одной простой причине: google выделяет разное колличество ресурсов для индексации того или иного домена. Называется краулинговый бюджет. Который прямо влияет в том числе на обьем работы совершаемой гуглом для индексации контента.
Чтобы тест стал корректным - следовало завести тестовый домен, о котором google ничего не знал ранее, а еще лучше хотябы 100.
И если бы авторы єто сделали, то обнаружили бы что мифы уже не такие и мифы.
Самый простой опыт - єто домен с контентом генерируемым на стороне клиента и такой-же в статике. Внезапно оказывается, что скорость индексации сравниваемых доменов отличается в разы.
Из материала, может сложиться ложное впечатление, будто бы typedArray играют какую-то важную роль в производительности всей задачи. Что может спровоцировать читателя в будущем использовать их вместо типичного ExoticObjectArray.
Вероятно, для информативности, следовало бы добавить, что любые typed array в js только тогда приобретают "мистические" черты супер-производительности, когда такие array можно передавать в неизменном виде в какое либо внешнее API. Например imageData от canvas.
Все же прочее, что делается с темже тайпедАррай, в современных агентах, подобных v8, работает с тойже производительностью. При єтом может быть причиной ее просадки именно в момент формарования отображения тайпед аррай на типичный js код.
То есть условный консоле.лог, примененрый к тайпед аррай, может привести к худшей производительности чем он же к exotic object array.
Вы заблуждаетесь.
1) web assembly не может быть быстрее js кода хотябы потому, что абстрактный wasm исполняется ровно тойже виртуальрой машиной что и абстрактный байткод, в который собирается в v8 js код.
wasm может быть более предсказуемым в случае, когда мы сталкиваемся с гарбаж коллектором и типизацией, чего в озвученном выше примере нет от слова совсем. GC задействован минимально. Типизация работает ровно также как в wasm typedArray.
2) простое копирование буфера в канвас, для случаев typedArray на порядок быстрее аналога в webGl. уже хотябы потому, что нет издержек на обслуживание каждого пикселя. webGl дал бы Вам прирост тогда, когда вы бы положили на gpu ваши условрые треугольники позволив gpu их красить самостоятельно. в примере выше обслуживается каждый пиксель отдельно. и тут не может быть ничего быстрее копирования буфера.
xms сам по себе никак не мог повлиять на запуск игр. от слова совсем.
исключение, если он отьедал памяти в первом 1024 сегменте столько, что остатка не хватало для запуска приложения. только тогда єто не проблема xms, а проблема доступной памяти в текущем окружении, крторую можно было решать исключая любые други приложерия.
к слову сказать. xms появился как способ дать временное окно перехода между dos и реал моде к виндовс и протектед моде. Дать апи, которое бы позволило запускать приложения в новой среде с минимальными издержками.
Дело в том, что уже с появления 286 процессора стало известно, как адресовать память выше 1мб без использования прослоек типа himem.sys. Единственным недостатком которого, являлась полная несовместимость реал мод,рс протектед мод. Но полностью прозрачный механизм адресации памяти.
Майкрасовт и прочих игроков рынка єто не сильно устраивало именно потому, что нужно было обеспечить бесшовныи переход с дос на виндовс.
В результате появляются франкинштейны вроде xms которые, по сути спекулируют на томже механизме, но предоставляя уровень абстракции єффектинвно заменяемый в новом окружении.