Javascript 数组参数在标记函数中不可扩展
通常,javascript中的数组是可扩展的,但对于作为标记函数的第一个参数传递的数组,情况并非如此:Javascript 数组参数在标记函数中不可扩展,javascript,ecmascript-6,tagged-templates,ecmascript-2018,Javascript,Ecmascript 6,Tagged Templates,Ecmascript 2018,通常,javascript中的数组是可扩展的,但对于作为标记函数的第一个参数传递的数组,情况并非如此: let ari=[1,2,3]; log(Object.isExtensible(ari)); //返回true 函数标记(ary,…表达式结果) { console.log(Array.isArray(ary)); //返回true log(Object.isExtensible(ari)); //返回false } 标签'test'您找对了位置。链接的规范甚至提供了一个关于原因的注释(e
let ari=[1,2,3];
log(Object.isExtensible(ari));
//返回true
函数标记(ary,…表达式结果)
{
console.log(Array.isArray(ary));
//返回true
log(Object.isExtensible(ari));
//返回false
}
标签'test'代码>您找对了位置。链接的规范甚至提供了一个关于原因的注释(emp.mine):
注2的程序代码中的每个TemplateLiteral与用于评估标记模板()的唯一模板对象相关联模板对象被冻结,并且每次评估特定标记的模板时都使用相同的模板对象
如果要了解实际执行情况,请首先查看标记模板的运行时语义,这些语义在:
12.3.7.1运行时语义:评估
MemberExpression:MemberExpression TemplateLiteral
[……]
返回?(tagFunc、tagRef、TemplateLiteral、tailCall)
如果您看一下抽象操作:
12.3.4.2运行时语义:EvaluateCall(func、ref、arguments、tailPosition)
[……]
让argList成为一组参数
因此,当使用模板文本调用标记函数时,TemplateLiteral的ArgumentListValuation将作为参数传递给标记函数。看看:
12.2.9.3运行时语义:ArgumentListValuation
TemplateLiteral:NoSubstitutionTemplate
[……]
让siteObj成为(templateLiteral)
看看这次行动,我们看到了罪魁祸首:
12.2.9.4运行时语义:GetTemplateObject(templateLiteral)
[……]
执行(模板“冻结”)
其中模板是传递给标记函数的数组。我们看到它被明确冻结了。如果您想更深一层,请参阅:
7.3.14设置整体水平(O级)
抽象操作SetIntegrityLevel用于修复对象自身的属性集。此抽象操作执行以下步骤:
[……]
让地位成为现实吧?O.[预防扩展]]()
看看一个普通的物体,我们看到这个操作叫做:
9.1.4.1常规预防扩展(O)
使用对象O调用抽象操作OrdinaryPreventExtensions时,将执行以下步骤:
将O.[Extensible]]设置为false
返回真值
因此[[Extensible]]内部插槽被显式设置为false。不确定规范中该部分的变量确切指的是什么,但是SetIntegrityLevel(someVar,“冻结”)。
听起来像是冻结了对象,这将使其不可扩展(步骤12和14)。我不喜欢这个数组不可扩展。明白为什么了。我希望我有你的理解能力。你的阐述对我很有帮助。