As For JavaScript Coalesce Expression - Nullish coalescing operator - ??
Abstract
О том, почему coalesce expression является идиотизмом притянутым в спецификацию идиотами не понимающими архитектуру языка, а так же о том как разработчики V8 реализовали эту парашу именно как парашу.
Что это такое ваше за Coalesce Expression - я забыл - напомни мне - я упырь
не волноваться, я тоже упырь и совершенно не понимаю как придумывают эти названия.
Потому вот документация и примеры:
Официальная спецификация ECMA
MDN
пример:
В чем проблема проверять и на null и на undefined одной конструкцией
Эта разница принципиальна для runtime. На основе этой информации RunTime может предпринимать совершенно разные шаги каким образом можно работать с нашим кодом. Очевидно, что идентификатор связанный с
По этой причине, Coalesce expression бесполезно так как включает в себя два пограничных случая, которые не пересекаются. Иными словами, если в Вашей программе Вы вынуждены проверять идентификатор на то может ли он быть связан в одной и той же ситуации с
Конечно если в Ваши задачи входит писать эффективный код. То есть код, который претендует на максимальную производительность.
Посмотрите на официальные API - если API должно вернуть обьект, но при этом что-то произошло, что не позволяет это сделать, то API всегда вернет null. Чем прямо сообщает RunTime - да я должен был вернуть обьект, но что-то пошло не так.
Байт код от V8 для Coalesce expression
Именно ради этого раздела я и затеял все это словоблудие.
JavaScript код:
Ldar - это загрузка содержимого регистра в регистр аккумулятора.
Регистр аккумулятора - это особенный уникальный регистр,
который существует в единственном числе в V8. Через него делаются практически все операции. */
на языке байткода V8 звучит как - если в регистре аккумулятора находится что-то
что является undefined или null то сделать переход к метке label1 */
Abstract
О том, почему coalesce expression является идиотизмом притянутым в спецификацию идиотами не понимающими архитектуру языка, а так же о том как разработчики V8 реализовали эту парашу именно как парашу.
Что это такое ваше за Coalesce Expression - я забыл - напомни мне - я упырь
не волноваться, я тоже упырь и совершенно не понимаю как придумывают эти названия.
Потому вот документация и примеры:
Официальная спецификация ECMA
MDN
пример:
var theThing;"
(theThing ?? "Yo");
// Если theThing связан с undefined или null результат вычисления выражения будет "Yo
В чем проблема проверять и на null и на undefined одной конструкцией
undefined
- это primitive value которое устанавливается для идентификаторов созданных при помощи variable statement.null- это primitive value которое связывают с идентификатором который в прошлом или в будущем был/будет связан с обьектом, но в его текущем состоянии обьект не определен. То есть null - это обьект с нулевой структурой. Не путать с указателями из других языков.
Эта разница принципиальна для runtime. На основе этой информации RunTime может предпринимать совершенно разные шаги каким образом можно работать с нашим кодом. Очевидно, что идентификатор связанный с
undefined
- это идентификатор поведение которого в будущем предсказать невозможно. Идентификатор связанный с null
- в будущем будет обьектом или ранее использовался как обьект. По этой причине, Coalesce expression бесполезно так как включает в себя два пограничных случая, которые не пересекаются. Иными словами, если в Вашей программе Вы вынуждены проверять идентификатор на то может ли он быть связан в одной и той же ситуации с
null
или undefined
- то у Вас проблемы с вашим кодом, его архитектурой. Так как если Вы знаете что Ваш идентификатор будет связан с обьектом в будущем - он обязан быть про инициализирован как null, а не undefined. Конечно если в Ваши задачи входит писать эффективный код. То есть код, который претендует на максимальную производительность.
Посмотрите на официальные API - если API должно вернуть обьект, но при этом что-то произошло, что не позволяет это сделать, то API всегда вернет null. Чем прямо сообщает RunTime - да я должен был вернуть обьект, но что-то пошло не так.
Байт код от V8 для Coalesce expression
Именно ради этого раздела я и затеял все это словоблудие.
JavaScript код:
var theThing;byteCode V8:
(theThing ?? "Yo");
Ldar r0/* Регистр r0 это наш идентификатор theThing.
Ldar - это загрузка содержимого регистра в регистр аккумулятора.
Регистр аккумулятора - это особенный уникальный регистр,
который существует в единственном числе в V8. Через него делаются практически все операции. */
JumpIfUndefinedOrNull "label1"/* Это непосредственно операция ??,
на языке байткода V8 звучит как - если в регистре аккумулятора находится что-то
что является undefined или null то сделать переход к метке label1 */
Jump "label2"// безусловный переход к метке label2
label1:// метка label1 к которой происходит переход
LdaConstant [0]// загрузить в аккумулятор подготовленную константу. В нашем случае это будет ссылка на "Yo"
label2:// метка label2 к которой происходит переход
Этот же код без комментариев:
// Other code
Ldar r0Ничего не покоробило в логике этого кода?
JumpIfUndefinedOrNull "label1"
Jump "label2"
label1:
LdaConstant [0]
label2:
🔥3
Выше была задача, которая спекулировала на символе @@toPrimitive
У этой задачи есть третий вариант, который я не отмечал для себя как значимый.
Однако, один из моих старых знакомых настоял на том, чтобы третий вариант условия этой задачи все-таки был озвучен:
С чем должен быть связан theObj
Не смотря даже на тот факт, что мне этот ответ кажется очевидным, а моему другу, который настоял на том, чтобы это условие прозвучало - ответ таким очевидным не кажется.
Ему ответ не кажется очевидным,
даже в условиях предыдущей задачи.
У этой задачи есть третий вариант, который я не отмечал для себя как значимый.
Однако, один из моих старых знакомых настоял на том, чтобы третий вариант условия этой задачи все-таки был озвучен:
С чем должен быть связан theObj
var theObj = ??? ;чтобы следующая строка кода:
console.log(theObj == 3, theObj == 'abc');
вернула true true
Учитывая тот факт, что Вы уже знаете ответ на предыдущую задачу, я не стану сразу спойлерить ответ на эту.Не смотря даже на тот факт, что мне этот ответ кажется очевидным, а моему другу, который настоял на том, чтобы это условие прозвучало - ответ таким очевидным не кажется.
Ему ответ не кажется очевидным,
даже в условиях предыдущей задачи.
Telegram
As For JS
Перебирая бумажки из прошлой жизни, нашел одно собеседование, где была такая задача:
Каким образом нужно инициализировать theIdent в коде:
var doExplAdd = (
(theValue, theNum)=>{
var theIdent = ????; //менять код можно только тут
return `${the…
Каким образом нужно инициализировать theIdent в коде:
var doExplAdd = (
(theValue, theNum)=>{
var theIdent = ????; //менять код можно только тут
return `${the…
❤5
Сегодня у меня хватило сил посмотреть какие-то комментарии под Видео: ⎡razbor:13⎦ Разбор видео: Выводим Мурыча на чистую воду от Дмитрия Карловского..
И больше всего меня тронул вот комментарий, где человек, как ему показалось, разобрался в сути происходящего:
он идет одним из самых первых (или последних).
Там же я написал ответ.
Этот комментарий прекресно иллюстрирует тот факт, почему JS нельзя изучать на примере спецификации, когда даже человек который потратил массу времени на написание этого комментария оказался неправ.
О чем я ему и написал в ответе, а именно, что он разбирает только специфический случай методов для которых согласно спецификации характерно гарантирование порядка ключей. Которое появились много позднее.
Особенно следует отметить, использование автором, для подверждения своей позиции цитат не имеющих отношения к официальным истоникам:
И так далее.
И больше всего меня тронул вот комментарий, где человек, как ему показалось, разобрался в сути происходящего:
Поймался Дремурыч! )) "Порядка ключей у пропертис никогда не было и не будет" - ты сам то понял, что сказал? Сам походу не читал спеку, давайте-ка ткнём его бородой в его любимую спецификацию:
в разделе ecma262, #sec-ordinaryownpropertykeys:
он идет одним из самых первых (или последних).
Там же я написал ответ.
Этот комментарий прекресно иллюстрирует тот факт, почему JS нельзя изучать на примере спецификации, когда даже человек который потратил массу времени на написание этого комментария оказался неправ.
О чем я ему и написал в ответе, а именно, что он разбирает только специфический случай методов для которых согласно спецификации характерно гарантирование порядка ключей. Которое появились много позднее.
Особенно следует отметить, использование автором, для подверждения своей позиции цитат не имеющих отношения к официальным истоникам:
While in ES5 explicitly no order has been specified, ES2015 defined an order in certain cases...
И так далее.
YouTube
⎡razbor:13⎦ Разбор видео: Выводим Мурыча на чистую воду от Дмитрия Карловского.
По многочисленным просьбам, максимально корректно, разберем видео от автора Мол Дмитрия Карловского.
Прохладные истории с постными лицами и унылый юмор - гарантирован.
Приходите, гарантировать что будет интересно я не могу, но то, что будет над чем подумать…
Прохладные истории с постными лицами и унылый юмор - гарантирован.
Приходите, гарантировать что будет интересно я не могу, но то, что будет над чем подумать…
👍15🔥3🤡1
Это ответ вот на эту "загадку" про Object String или задача с двумя подводными камнями.
1. Object String согласно спецификации - это экзотический обьект. Что означает, что поведение этого обьекта, хотя-бы в одном из 12 стандартных поведений обьекта переопределено.
Одно из таких поведений как раз касается поведения в случае поиска данных которых связаны с ключами из множества indexed property. (Если не до конца корректно и максимально доходчиво то это множество числовыми ключей из диапазона 0 - 2^32 - 1. Некорректно потому - что в JS не существует числовых ключей у Object. Только ключи типа String и Symbol)
Это поведение, возвращает substring string.
Что это означает:
Если отвечать на вопрос строго формально, то с точки зрения спецификации, при создании Object String под каждый ключ, не создается отдальная строка. Геттер это делает только тогда, когда произошел запрос по конкретному индексу.
При этом, тот самый геттер, возвращает именно строку - то есть формально ее создает.
В результате первый подводный камень - до тех пор пока, не было обращения по конкретному индексу, спецификация не требует создания отдельной строки на каждый символ (Code Unit)
В то же время при обращении по индексу, такая строка должна быть создана.
Как следствие, попытка вызова любого console.dir, так как он показывает все что связано с каждым индексом, формально обязан создать все строки - так как должен обратиться к каждому геттеру.
То есть создать три строки: 'a', 'b', 'c'
Это все еще не все
Все что сказано Выше касается спецификации. А что в реальности V8?
В реальности V8, уже существуют описания для символов из диапазона US ASCII .
То есть при обращению к строке вида:
ничего страшного не случится, потому что обьект описывающий US ASCII - "a" уже заранее создан. И мы всего лишь свяжем идентификатор с ссылкой окторая давно создана.
То есть даже в случае
ничего страшного не будет, так как для US ASCII a, b, c - все обьекты созданы еще на старте V8.
И проблемы могут начаться только там, где внутри V8, на момент старта не создано заранее готовых обьектов для Code Unitov используемых в строке.
Например кирилицы.
1. Object String согласно спецификации - это экзотический обьект. Что означает, что поведение этого обьекта, хотя-бы в одном из 12 стандартных поведений обьекта переопределено.
Одно из таких поведений как раз касается поведения в случае поиска данных которых связаны с ключами из множества indexed property. (Если не до конца корректно и максимально доходчиво то это множество числовыми ключей из диапазона 0 - 2^32 - 1. Некорректно потому - что в JS не существует числовых ключей у Object. Только ключи типа String и Symbol)
Это поведение, возвращает substring string.
Что это означает:
Если отвечать на вопрос строго формально, то с точки зрения спецификации, при создании Object String под каждый ключ, не создается отдальная строка. Геттер это делает только тогда, когда произошел запрос по конкретному индексу.
При этом, тот самый геттер, возвращает именно строку - то есть формально ее создает.
В результате первый подводный камень - до тех пор пока, не было обращения по конкретному индексу, спецификация не требует создания отдельной строки на каждый символ (Code Unit)
В то же время при обращении по индексу, такая строка должна быть создана.
Как следствие, попытка вызова любого console.dir, так как он показывает все что связано с каждым индексом, формально обязан создать все строки - так как должен обратиться к каждому геттеру.
То есть создать три строки: 'a', 'b', 'c'
Это все еще не все
Все что сказано Выше касается спецификации. А что в реальности V8?
В реальности V8, уже существуют описания для символов из диапазона US ASCII .
То есть при обращению к строке вида:
var theStr = `abc`;
var theFirst = theStr[0];
ничего страшного не случится, потому что обьект описывающий US ASCII - "a" уже заранее создан. И мы всего лишь свяжем идентификатор с ссылкой окторая давно создана.
То есть даже в случае
var theStr = `abc`;
console.dir( theStr );
ничего страшного не будет, так как для US ASCII a, b, c - все обьекты созданы еще на старте V8.
И проблемы могут начаться только там, где внутри V8, на момент старта не создано заранее готовых обьектов для Code Unitov используемых в строке.
Например кирилицы.
Telegram
As For JS
Задача для тех кому нечем заняться.
Object String или задача с двумя подводными камнями.
Оценим обьект, который создан при помощи конструктора String.
Воспользуемся для этого любым доступным инструментом:
console.dir( new String("abc") );
развернув сформированный…
Object String или задача с двумя подводными камнями.
Оценим обьект, который создан при помощи конструктора String.
Воспользуемся для этого любым доступным инструментом:
console.dir( new String("abc") );
развернув сформированный…
❤9👍1