Автор: dSalieri
Версия ECMAScript, используемая в объяснении: Draft ECMA-262 / June 24, 2022
Версия WHATWG, используемая в объяснении: Living Standard - 22 August 2022
Последнее изменение документа: 13.12.2022
/// Don't use interval less 5ms because web agents can't provide delay less than 4ms in due with optimization in nested setTimeout calls | |
/// But how the practice shows 5ms is lower border for this timer, because it accounts errors and evaluates corrected interval. That's is why 5ms the lowest interval of this timer. | |
function timer(callback, interval, duration, ...args) { | |
if (typeof callback !== "function") return; | |
const toNumberPositive = (value) => { | |
const n = Number(value); | |
return (n !== n || n < 0) ? 0 : n | |
}; | |
Автор: dSalieri
Версия ECMAScript, используемая в объяснении: Draft ECMA-262 / June 24, 2022
Версия WHATWG, используемая в объяснении: Living Standard - 22 August 2022
Последнее изменение документа: 13.12.2022
Вопрос:
Почему функция внутри Block
не всегда перезаписывает глобальный идентификатор?
Код:
/// пример 1
{
function a() {}
}
console.log(a); /// f a() {}
Автор: dSalieri
Версия ECMAScript, используемая в объяснении: Draft ECMA-262 / February 19, 2024
Последнее изменение документа: 20.02.2024
Important
Раздел посвященный устройству спецификации [execution contexts][execution-contexts]. Так как спецификация сама отлично описывает данный механизм, то решено было просто перевести с внедрением некоторых пояснительных сносок.
Реализация двух конструкторных функций Promise.resolve
и Promise.reject
Алгоритмы имеют зависимость от NewPromiseCapability
Изначально этот файл демонстрировал внутреннюю операцию [NewPromiseCapability] на языке js. Не так давно в 14 версию ECMAScript интегрировали API [Promise.withResolvers]. И всвязи с этим я хочу кое-что пояснить.
Для начала вспомним операцию [NewPromiseCapability]:
function NewPromiseCapability(C){
if (!(C.prototype && C.prototype.constructor === C && typeof C === "function")) throw TypeError("C is not a constructor");
const resolvingFunctions = {
resolve: undefined,
reject: undefined,
Цель: Расширить определение типов данных / Сделать работу с типами более гибкими
Чтобы проверить является ли функция [конструкторной][constructor], нужно посмотреть есть ли у нее поле [[Construct]]
. Нет ни единого варианта проверить это [напрямую][isconstructor].
Но есть два способа, которые мне известны:
[[Construct]]
, используя интерфейсы, которые это делают (медленнее).К первому типу относится реализация prototype.js
, ко второму newTarget.js
, bind.js
, proxy.js
и reflect.js
.
Также существует одна весомая разница; при проверке в newTarget.js
, bind.js
, proxy.js
и reflect.js
мы используем [[Construct]]
поле, которое вызывается через операцию [Construct][construct-op] для создания объекта, чтобы убедиться, что объект создан, тем самым это докажет, что функция является конструкторной, но в этом и опасность если произойдет ошибка в алгоритме [[Construct]]
проверяемая функция не пройдет проверку.
/// Эта функция отсылка к спецификационному алгоритму https://tc39.es/ecma262/#sec-speciesconstructor | |
/// Смысл операции извлечь конструктор для переданного объекта | |
/* | |
Наверное вас смущает, что первая строчка кода могла бы решить этот вопрос, | |
но особенность в том что есть [Symbol.species], через который можно сообщить что использовать значение из | |
"constructor" вы не хотите, а хотите возспользоваться чем-то другим, решение - [Symbol.species] | |
*/ | |
function SpeciesConstructor(O, defaultConstructor){ | |
const C = Reflect.get(O, "constructor"); | |
if(C === undefined) return defaultConstructor; |
Очень интересная тема, на которой я давненько съел собаку при изучении. Теперь хотелось бы помочь закрыть чей-нибудь гештальт при изучении javascript.
Так как поведение внутренних механизмов изменилось со временем, то я обязан учесть этот факт. Итак начнем мы с ядра этого механизма, а затем рассмотрим частные случаи.
Алгоритм ToPrimitive(input[,preferredType]):
The abstract operation ToPrimitive takes argument input (an ECMAScript language value) and optional argument preferredType (string or number). It converts its input argument to a non-Object type. If an object is capable of converting to more than one primitive type, it may use the optional hint preferredType to favour that type. It performs the following steps when called:
1. If Type(input) is Object, then
a. Let exoticToPrim be ? GetMethod(input, @@toPrimitive).