可能是一个天真的问题-如果执行这个片段(我使用Node.jsv12.16.3
运行,除了错误类型之外,Chrome中的结果相同(:
const obj = {}
Object.defineProperty(obj, 'a', {
writable: false,
value: 13
})
obj.a = 14
很明显,它会抛出一个错误,但该错误的消息字符串有一个奇怪的对象表示:
TypeError:无法分配给对象'#<的只读属性'a';对象>'
问题是-为什么它被字符串化为#<Object>
?
在对象上定义toString
方法将使其呈现为使用Object.prototype.toString.call(obj)
:调用的方法
const obj = {
toString () {
return 'stringified obj'
}
}
Object.defineProperty(obj, 'a', {
writable: false,
value: 13
})
console.log(`${obj}`)
obj.a = 14
TypeError:无法分配给对象'[object object]'的只读属性'a'
当console.log
正确输出时。如何使TypeError
输出正确的字符串表示?它在内部使用什么?
它使用模板:
T(StrictReadOnlyProperty,
"Cannot assign to read only property '%' of % '%'")
这反过来又被插值为对象的构造函数名称。在这种情况下,Object
。你可以看到:
const obj = {};
obj.constructor.name; // Object
const obj2 = new class Bar {};
obj2.constructor.name; // Bar
或者,在您的示例中:
const obj = new class SomeValue {}
Object.defineProperty(obj, 'a', {
writable: false,
value: 13
})
// TypeError: Cannot assign to read only property 'a' of object '#<SomeValue>'
obj.a = 14
请注意,规范只是说:";引发TypeError异常"-这种行为完全由V8引擎而非JavaScript定义。