根据ES5.1规范,该程序"use strict;" "foo".bar = 42;
导致String
要创建的对象,分配给它的属性,然后扔掉该对象,导致没有可观察到的效果 - 包括任何异常。 (可以通过在 Opera 12 等兼容 ES5 的 JS 实现中尝试来确认是否没有效果。)
在现代 JS 实现中,它会抛出一个TypeError
相反,尝试一下:
"use strict"; "foo".bar = 42;
我很确定新的行为是 ES6 规范强制执行的,但是尽管多次阅读相关部分,我还是看不到它在哪里指定TypeError
被扔掉。实际上,关键部分 https://www.ecma-international.org/ecma-262/6.0/index.html#sec-putvalue似乎没有变化:
6.2.3.2 看跌期权(V, W)#
- 如果突然返回(V).
- 如果突然返回(W).
- If Type(V) 不是参考,抛出一个参考错误例外。
- Let base是 GetBase(V).
- If IsUnresolvableReference(V) is true, then
- Else if IsPropertyReference(V) is true, then
- a. If HasPrimitiveBase(V) is true, then
- 我。断言:在这种情况下,base永远不会为空或未定义。
- ii. Set base到对象(base).
- b. Let 成功了 be ? base.[[设置]](获取参考名称(V), W, 获取这个值(V)).
- C。如果突然返回(成功了).
- d. If 成功了为 false 且 IsStrictReference(V) 为真,抛出一个类型错误例外。
- e.返回。
- …
规范(ES6 或更高版本)在哪里强制抛出TypeError
?
我想它就在这里:
http://www.ecma-international.org/ecma-262/7.0/#sec-ordinaryset http://www.ecma-international.org/ecma-262/7.0/#sec-ordinaryset
9.1.9.1.普通集(O、P、V、接收器)
[...]
4.b.如果 Type(Receiver) 不是 Object,则返回 false。
(以前称为 [[Set]],在ES6 §9.1.9 https://www.ecma-international.org/ecma-262/6.0/index.html#sec-ordinary-object-internal-methods-and-internal-slots-set-p-v-receiver.)
虽然PutValue
促进base
对于一个对象,它不会对接收者做同样的事情——GetThisValue(V)
仍然调用原来的V
(具有原始基础)。所以,GetThisValue
返回一个原语,OrdinarySet.4b
无法分配新创建的ownDesc
并返回false
,这又导致PutValue.6d
抛出 TypeError,前提是引用是严格的。
V8的相应部分似乎遵循相同的逻辑:
Maybe<bool> Object::AddDataProperty(....
if (!it->GetReceiver()->IsJSReceiver()) {
return CannotCreateProperty(...
https://github.com/v8/v8/blob/3b39fc4dcdb6593013c497fc9e28a1d73dbcba03/src/objects.cc#L5140 https://github.com/v8/v8/blob/3b39fc4dcdb6593013c497fc9e28a1d73dbcba03/src/objects.cc#L5140
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)