Аргумент массива не расширяется в функции тега - PullRequest
0 голосов
/ 17 декабря 2018

Как правило, массивы в javascript являются расширяемыми, но это не так для массива, переданного в качестве первого аргумента функции тега:

let ary = [1,2,3];
console.log(Object.isExtensible(ary));
// returns true

function tag(ary, ...expressionResults)
{
    console.log(Array.isArray(ary));
    //returns true
    console.log(Object.isExtensible(ary));
    // returns false
}
tag`test`;

Где именно в спецификации этот массив считается нерасширяемым?Я даже не уверен, смотрю ли я в правильное пятно .

1 Ответ

0 голосов
/ 17 декабря 2018

Вы искали в правильном месте.Связанная спецификация даже предлагает примечание относительно того, почему (emp. Mine):

NOTE 2 Каждый TemplateLiteral в программном коде область связана с уникальным объектом шаблона, который используется при оценке тегированных шаблонов ( 12.2.9.6 ). Объекты шаблона заморожены и один и тот же объект шаблона используется каждый раз, когда оценивается определенный помеченный шаблон.

Если вы хотите понять фактическое выполнение, сначала посмотрите на семантику выполнения тегированных шаблонов, указанную в Раздел 12.3.7.1 :

12.3.7.1 Семантика времени выполнения: оценка

Выражение участника: TemplateExpression TemplateLiteral

[…]

Вернуть? EvaluateCall ( tagFunc , tagRef , TemplateLiteral , tailCall ).

Если вы посмотрите на абстрактную операцию EvaluateCall :

12.3.4.2 Семантика времени выполнения: EvaluateCall ( func , ref , аргументы , tailPosition )

[…]

Пусть argList будет ArgumentListEvaluation из аргументов .

Итак, при вызове функции тега с шаблономЛитерал, ArgumentListEvaluation для TemplateLiteral передается в качестве аргумента функции тега.Взгляните на ArgumentListEvaluation :

12.2.9.3 Семантика времени выполнения: ArgumentListEvaluation

TemplateLiteral: NoSubstitutionTemplate

[...]

Пусть siteObj будет GetTemplateObject ( templateLiteral ).

Просмотр операции GetTemplateObject мы видим виновника:

12.2.9.4 Семантика времени выполнения: GetTemplateObject ( templateLiteral )

[…]

Выполнить SetIntegrityLevel ( шаблон , «заморожен»).

Где шаблон - массив, переданный вфункция тега.Мы видим, что он явно заморожен.Если вы хотите пройти уровень глубже, см. SetIntegrityLevel :

7.3.14 SetIntegrityLevel ( O , level )

Абстрактная операция SetIntegrityLevel используется для исправления набора собственных свойств объекта.Эта абстрактная операция выполняет следующие шаги:

[…]

Пусть статус будет? O . [[PreventExtensions]] ().

И, взглянув на [[PreventExtensions]] обычного объекта, мывидим, что вызывается операция OrdinaryPreventExtensions :

9.1.4.1 OrdinaryPreventExtensions ( O )

Когда абстрактная операция OrdinaryPreventExtensions вызывается с ObjectO, предпринимаются следующие шаги:

  1. Установить O . [[Extensible]] на false .
  2. Return правда .

Таким образом, внутренний слот [[Extensible]] явно установлен на false.

...