Вопрос:
Почему функция внутри Block не всегда перезаписывает глобальный идентификатор?
Код:
/// пример 1
{
function a() {}
}
console.log(a); /// f a() {}Вопрос:
Почему функция внутри Block не всегда перезаписывает глобальный идентификатор?
Код:
/// пример 1
{
function a() {}
}
console.log(a); /// f a() {}Как выглядит это внутри:
Оператор ||:
LogicalORExpression : LogicalORExpression || LogicalANDExpression
1. Let lref be the result of evaluating LogicalORExpression. 2. Let lval be ? GetValue(lref). 3. Let lbool be ! ToBoolean(lval). 4. If lbool is true, return lval. 5. Let rref be the result of evaluating LogicalANDExpression.
Вопрос: Есть две цепочки promise, которые выводят сообщения в консоль. Первый выводит: tick1, tick2, tick3. Второй: tick3, tick1, tick2
Код 1:
/// Код 1
const p = new Promise(resovle => setTimeout(resovle));
new Promise(resolve => resolve(p)).then(() => {
console.log("tick 3");
});Наверное многие при изучении javascript сталкиваются с проблемой понимания. Что ж сейчас я попытаюсь вам объяснить механизм работы ключевого слова this.
Для начала давайте рассмотрим алгоритм исполнения ключевого слова this в спецификации.
Итак смотрим на производство PrimaryExpression: this и видим следующие шаги:
1. Return ? ResolveThisBinding().И это все. Но было бы не честно не раскрыть механизм этого шага, поэтому продолжим...
Теперь смотрим алгоритм ResolveThisBinding и наблюдаем такие этапы:
[Смотрю я как-то на эту статью][learnjs] и даже как-то печально, что отсутствует объяснение на счет экзотического вызова функции [bind][bind].
Давайте я расскажу чем отличается обычный вызов функции от экзотического вызова функции [bind][bind].
Смотрите, у обычной функции, которую вы обычно определяете в своем коде, при ее создании создаются для нее специфические поля [[[Call]]][ordinary-call] (для любой функции) и [[[Construct]]][ordinary-construct] (только для обычных функций, функций-классов, функций созданных через конструктор Function). После создания, обычный вызов функции пользуется полем [[[Call]]][ordinary-call], при создании экземпляра используется [[[Construct]]][ordinary-construct].
a();new a();История с функцией, которая создает функцию [bind][bind] аналогичная, но есть одно но. Эта функция при создании определяет другое поведение для [[[Call]]][bind-call] и [[[Construct]]][bind-construct]. Но помимо этих пол
Изначально этот файл демонстрировал внутреннюю операцию [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,| /// Эта функция отсылка к спецификационному алгоритму 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; |
Реализация Promise.prototype.finally
Имеет зависимость от SpeciesConstructor
Реализация двух конструкторных функций Promise.resolve и Promise.reject
Алгоритмы имеют зависимость от NewPromiseCapability
Чтобы проверить является ли функция [конструкторной][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]] проверяемая функция не пройдет проверку.