草庐IT

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

coder 2023-05-30 原文

我刚刚观察到以下奇怪的行为:

删除 undefined variable

> 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

我有两个问题:

  • 为什么 delete a 有效,而 a 未定义?
  • 为什么删除a.bar.something会抛出错误Cannot convert null to object而不是Cannot read property 'something' of undefined (因为 a.barundefined)?

根据文档 delete 运算符从对象中删除属性。,所以第一个问题的答案是 a 是应该是 this 对象的属性?

c++ 中使用 delete a; 时应用程序,出现此错误(它应该这样做)error: ‘a’ was not declared in this scope.

最佳答案

答案分为两部分。第一个描述不多,但回答了这个问题,而后者则进入了规范的基本细节。

tl;博士

  1. 第一行有效,因为在非严格模式下,尝试删除变量才有效。
  2. 第一部分的其余示例不起作用,因为未定义 a
  3. delete a.foo 有效,因为没有理由不这样做
  4. delete a.bar.something 抛出,因为它首先尝试将 a.bar 转换为对象,然后再尝试访问 a.bar.something

现在完全不同了

首先,让我们明确两段代码在概念上是不同的,因为第一段讨论的是一个未声明的变量。

我们将关注 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

所有这些行都试图用 a 做一些事情,这是一个未声明的变量。因此,您会得到一个 ReferenceError。到目前为止一切顺利。

> delete a
true

这进入 delete 语句的第 3 个子句:a 是一个“未解析的引用”,这是说“它没有被声明”的一种奇特方式. Spec 说在这种情况下简单地返回 true

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

这很直观,正如您所期望的那样(可能),但无论如何让我们深入研究一下。 delete 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.

哎呀,这是一大堆无趣的东西。让我们忽略 [[Delete]] 部分之后的所有内容,只看 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)) [...]

我突出显示了与此特定片段相关的部分。在我们尝试delete 任何东西之前,规范告诉我们调用ToObject(GetBase(ref)),其中ref = a.bar.something。那就这样吧!

  • GetBase (a.bar.something) === a.bar
  • ToObject (a.bar) === ToObject(undefined) 抛出 TypeError

这解释了最终的行为。

最后说明:您显示的错误消息具有误导性,因为它说它试图将 null 转换为一个对象,但它没有,因为它试图转换 undefined 合二为一。最新的 chrome 和 firefox 抛出了一个更准确的版本,但我认为 v8 只是最近才修复了错误消息,所以升级到 node v11 可能会显示正确的版本。

关于javascript - 删除不存在的字段的子字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26927605/

有关javascript - 删除不存在的字段的子字段的更多相关文章

  1. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  2. ruby - 我可以使用 Ruby 从 CSV 中删除列吗? - 2

    查看Ruby的CSV库的文档,我非常确定这是可能且简单的。我只需要使用Ruby删除CSV文件的前三列,但我没有成功运行它。 最佳答案 csv_table=CSV.read(file_path_in,:headers=>true)csv_table.delete("header_name")csv_table.to_csv#=>ThenewCSVinstringformat检查CSV::Table文档:http://ruby-doc.org/stdlib-1.9.2/libdoc/csv/rdoc/CSV/Table.html

  3. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  4. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  5. ruby - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

    我发现ActiveRecord::Base.transaction在复杂方法中非常有效。我想知道是否可以在如下事务中从AWSS3上传/删除文件:S3Object.transactiondo#writeintofiles#raiseanexceptionend引发异常后,每个操作都应在S3上回滚。S3Object这可能吗?? 最佳答案 虽然S3API具有批量删除功能,但它不支持事务,因为每个删除操作都可以独立于其他操作成功/失败。该API不提供任何批量上传功能(通过PUT或POST),因此每个上传操作都是通过一个独立的API调用完成的

  6. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  7. ruby - 如何安全地删除文件? - 2

    在Ruby中是否有Gem或安全删除文件的方法?我想避免系统上可能不存在的外部程序。“安全删除”指的是覆盖文件内容。 最佳答案 如果您使用的是*nix,一个很好的方法是使用exec/open3/open4调用shred:`shred-fxuz#{filename}`http://www.gnu.org/s/coreutils/manual/html_node/shred-invocation.html检查这个类似的帖子:Writingafileshredderinpythonorruby?

  8. ruby-on-rails - rspec - 如何检查方法是否存在? - 2

    我的模型有defself.empty_building//stuffend我怎样才能对这个现有的进行rspec?,已经尝试过:describe"empty_building"dosubject{Building.new}it{shouldrespond_to:empty_building}endbutgetting:Failure/Error:it{shouldrespond_to:empty_building}expected#torespondto:empty_building 最佳答案 你有一个类方法self.empty_bu

  9. ruby-on-rails - 标准化文件名的字符串,删除重音和特殊字符 - 2

    我正在尝试找到一种方法来规范化字符串以将其作为文件名传递。到目前为止我有这个:my_string.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]/n,'').downcase.gsub(/[^a-z]/,'_')但第一个问题:-字符。我猜这个方法还有更多问题。我不控制名称,名称字符串可以有重音符、空格和特殊字符。我想删除所有这些,用相应的字母('é'=>'e')替换重音符号,并将其余的替换为'_'字符。名字是这样的:“Prélèvements-常规”“健康证”...我希望它们像一个没有空格/特殊字符的文件名:“prelevements_routin

  10. ruby-on-rails - ActiveRecord 的 find_or_create* 方法是否存在根本性缺陷? - 2

    有几种方法:first_or_create_by、find_or_create_by等,它们的工作原理是:与数据库对话以尝试找到我们想要的东西如果我们找不到,就自己做保存到数据库显然,并发调用这些方法可能会使两个线程都找不到它们想要的东西,并且在第3步中一个线程会意外失败。似乎更好的解决方案是,创建或查找即:提前在您的数据库中创建合理的唯一性约束。如果你想保存一些东西,就保存它如果有效,那就太好了。如果它因为RecordNotUnique异常而无法工作,它已经存在,太好了,加载它那么在什么情况下我想使用Rails内置的东西而不是我自己的(看起来更可靠)create_or_find?

随机推荐