javascript – 删除不存在的字段的子字段

前端之家收集整理的这篇文章主要介绍了javascript – 删除不存在的字段的子字段前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我刚刚观察到以下奇怪的行为:

删除未定义的变量

> 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

删除不存在的字段的子字段

> a = {}
{}
> delete a.foo
true
> delete a.bar.something
TypeError: Cannot convert null to object
> a.bar
undefined

我有两个问题:

>为什么在没有定义的时候删除作品?
>为什么删除a.bar.something会抛出错误无法将null转换为对象,而不能读取未定义的属性“something”(因为a.bar未定义)?

根据文档delete操作符从对象中删除一个属性,所以第一个问题的答案是a应该是这个对象的属性

当使用delete a;在c++应用程序中,此错误出现(应该做)错误:’a’未在此范围内声明.

解决方法

答案分为两部分.第一个不是很多,但是回答这个问题,而后者则说明了细节.

TL;博士

>第一行工作原理是因为在非严格模式下,试图删除一个变量只是工作.
>第一节中的其余例子不起作用,因为没有定义
>删除a.foo的作品,因为没有理由不应该
>删除a.bar.something throws,因为它首先尝试在尝试访问a.bar.something之前将a.bar转换为对象.

现在对于完全不同的东西

首先,让我们明确地说,这两个代码段在概念上是不同的,因为第一个谈到一个没有声明的变量.

我们会在how delete is specified看一下.

让我们从容易理解的部分开始:

> 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

所有这些行都试图用一个没有声明的变量来做某事.所以你得到一个ReferenceError.到现在为止还挺好.

> delete a
true

这就是删除声明的第3条:a是一个“未解决的引用”,这是一种说“没有被声明”的花哨的方式.规范说在这种情况下只是回归真实.

> a = {}
{}
> delete a.foo
true

这个人的直观性,正如你所期望的(可能),但让我们深入其中.删除obj.property进入第4条款:

Return the result of calling the [[Delete]] internal method on ToObject(GetBase(ref)) providing GetReferencedName(ref) and IsStrictReference(ref) as the arguments.

Welp是一大堆无趣的东西.让我们忽略[[删除]]部分之后的所有内容,只要看看how [[Delete]] is specified.如果我用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!?');
}

在这个例子中,a没有一个名为foo的属性,所以没有什么特别的.

现在变得有趣了

> delete a.bar.something
TypeError: Cannot convert null to object

这是因为我们以前忽略的一些不感兴趣的事情:

Return the result of calling the [[Delete]] internal method on ToObject(GetBase(ref)) […]

我突出显示了与此特定片段相关的部分.在我们尝试删除任何东西之前,spec告诉我们调用ToObject(GetBase(ref)),其中ref = a.bar.something.那我们来做吧

> GetBase(a.bar.something)=== a.bar
> ToObject(a.bar)===引用TypeError的ToObject(undefined)

这解释了最终的行为.

最后说明:您显示错误消息是误导性的,因为它表示尝试将null转换为一个对象,它没有,因为它尝试将未定义转换为一个.最新的chrome和firefox抛出一个更准确的一个,但是我觉得v8最近才修复了错误信息,所以也许升级到节点v11会显示一个正确的版本.

猜你在找的JavaScript相关文章