Ion*_*zău 10 javascript c++ node.js
我刚观察到以下奇怪的行为:
> delete a
true
> delete a[0]
ReferenceError: a is not defined
> delete a.something
ReferenceError: a is not defined
> delete a.something[0]
ReferenceError: a is not defined
Run Code Online (Sandbox Code Playgroud)
> a = {}
{}
> delete a.foo
true
> delete a.bar.something
TypeError: Cannot convert null to object
> a.bar
undefined
Run Code Online (Sandbox Code Playgroud)
我有两个问题:
delete a工作时a没有定义?a.bar.something抛出的错误Cannot convert null to object,而不是Cannot read property 'something' of undefined(因为a.bar是undefined)?根据文档的delete操作者,将删除该对象的属性.,那么第一个问题的答案a是应该是this对象的属性?
delete a;在c ++应用程序中使用时,会出现此错误(并且应该这样做)error: ‘a’ was not declared in this scope.
答案分为两部分.第一个没有描述,但回答了问题,而后者则涉及规范的细节.
a未定义delete a.foo 因为没有理由不应该这样做delete a.bar.something抛出因为它a.bar在尝试访问之前首先尝试变成对象a.bar.something.首先,让我们清楚地说明,代码的两个部分在概念上是不同的,因为第一部分讨论了未声明的变量.
我们将看看如何delete指定相当多.
让我们从更容易理解的部分开始:
> delete a[0]
ReferenceError: a is not defined
> delete a.something
ReferenceError: a is not defined
> delete a.something[0]
ReferenceError: a is not defined
Run Code Online (Sandbox Code Playgroud)
所有这些行都试图做一些事情a,一个未声明的变量.因此,你得到一个ReferenceError.到现在为止还挺好.
> delete a
true
Run Code Online (Sandbox Code Playgroud)
这进入了delete声明的第3个条款:a是一个"未解决的引用",这是一种说"它没有被声明"的奇特方式.Spec说true在这种情况下简单地返回.
> a = {}
{}
> delete a.foo
true
Run Code Online (Sandbox Code Playgroud)
这个直观,如你所料(可能),但无论如何让我们深入研究它.delete obj.property进入第4条:
返回
[[Delete]]在ToObject(GetBase(ref))提供时调用内部方法的结果GetReferencedName(ref)并IsStrictReference(ref)作为参数.
Welp那是一件很无趣的事情.让我们忽略[[Delete]]零件之后的所有内容,然后看一下如何[[Delete]]指定.如果我用js写它,它就是这样的:
function Delete (obj, prop) {
var desc = Object.getOwnPropertyDescriptor(obj, prop);
if (!desc) {
return true;
}
if (desc.configurable) {
desc.magicallyRemove(prop);
return true;
}
throw new TypeError('trying to delete a non-configurable property, eh!?');
}
Run Code Online (Sandbox Code Playgroud)
在示例中,a没有名为的属性foo,因此没有什么特别的事情发生.
现在它变得有趣:
> delete a.bar.something
TypeError: Cannot convert null to object
Run Code Online (Sandbox Code Playgroud)
这是因为我们之前忽略了一些无趣的事情:
返回
[[Delete]]在ToObject(GetBase(ref))[...] 上调用内部方法的结果
我突出显示了与此特定代码段相关的部分.在我们尝试delete任何事情之前,规范告诉我们打电话ToObject(GetBase(ref)),在哪里ref = a.bar.something.那我们就这样做吧!
这解释了最终的行为.
最后的注意事项:您显示的错误消息具有误导性,因为它表示它试图转换null为一个对象,但它没有尝试转换为一个对象undefined.最新的chrome和firefox抛出更准确的一个,但我认为v8最近才修复了错误信息,所以升级到节点v11可能会显示正确的版本.
| 归档时间: |
|
| 查看次数: |
1331 次 |
| 最近记录: |