【发布时间】:2018-09-15 21:12:59
【问题描述】:
根据 ES5.1 规范,程序 "use strict;" "foo".bar = 42; 导致创建 String 对象,分配给它的属性,然后将对象扔掉,导致没有可观察到的效果 - 包括任何异常。 (可以通过在类似 Opera 12 中的 ES5 兼容 JS 实现中尝试来确认没有效果。)
在现代 JS 实现中,它会抛出一个 TypeError 来代替——试试吧:
"use strict"; "foo".bar = 42;
我很确定新行为是 ES6 规范强制要求的,但是尽管多次阅读相关部分,但我看不到在哪里指定 TypeError 被抛出。事实上,the key parts 似乎没有改变:
6.2.3.2 PutValue (V, W)#
- ReturnIfAbrupt(V).
- ReturnIfAbrupt(W).
- 如果 Type(V) 不是 Reference,则抛出 ReferenceError 异常。
- 设 base 为 GetBase(V)。
- 如果 IsUnresolvableReference(V) 为真,则
- …
- 否则,如果 IsPropertyReference(V) 为真,则
- 一个。如果 HasPrimitiveBase(V) 为真,则
- i.断言:在这种情况下,base 永远不会为 null 或未定义。
- 二。将 base 设置为 ToObject(base)。
- 乙。让成功成为? base.[[Set]](GetReferencedName(V), W, GetThisValue(V)).
- c。 ReturnIfAbrupt(成功)。
- d.如果 succeeded 为 false 且 IsStrictReference(V) 为 true,则抛出 TypeError 异常。
- e.返回。
- …
规范(ES6 或更高版本)要求在哪里抛出 TypeError?
【问题讨论】:
-
我也没有在 Annex C 看到它。
-
我开始怀疑这实际上根本不在规范中。
-
这里是它进入 V8 的地方,像往常一样没有引用:codereview.chromium.org/408183002 现在看看其他人。
-
我的期望是
ToObject会显式返回一个不可扩展的String,因此[[Set]]会返回 false 并且第 6 步会抛出,但我实际上并没有看到它定义了字符串对象是不可扩展的。 -
@Paulpro:创建一个字符串对象,使用
Object.preventExtensions将其设置为不可扩展,并尝试在严格模式下对其设置属性会产生不同的错误消息,其中提到“对象不可扩展”。对于问题中的情况,它似乎根本没有经过对象。
标签: javascript ecmascript-6 typeerror ecmascript-5 primitive