jjzjj

javascript - 删除不合格标识符时严格模式语法错误背后的动机?

coder 2024-05-07 原文

我无法理解为什么在严格模式下,当 delete 用于非限定标识符时会发生语法错误。

在大多数情况下,这是有道理的...如果您以通常的方式使用 var 关键字声明变量,然后尝试对它们使用 delete,在非严格模式下,它会悄无声息地失败,因此在这些情况下,严格模式因错误而失败是有意义的。

但是,有些情况下您不能删除合格的标识符:

(function() {

  // "use strict";

  var obj = Object.create({}, { bloop: { configurable: false } });

  delete obj.bloop; // throws TypeError in strict mode, silently fails in non-strict.

  console.log('bloop' in obj); // true

}());

严格模式必须在这里做一个运行时检查,因为遇到这个会抛出TypeError。还有一些情况你可以在非严格模式下成功删除不合格的标识符...

// "use strict";

window.bar = 6;

console.log(typeof bar); // number

delete bar; // works in non-strict, syntax error in strict!

console.log(typeof bar); // undefined

事实上,据我了解,是否可以删除东西(在非严格模式下)取决于内部的 [[Configurable]] 属性,与限定标识符无关.据我所知,在严格模式下无法删除(作为本地 VO 的属性) 可配置的非全局变量:

(function() {

  // "use strict";

  eval('var foo = 5;');

  console.log(typeof foo); // number

  delete foo; // works in non-strict, SyntaxError in strict.

  console.log(typeof foo); // undefined

}());

所以,我的问题是,当在非限定标识符上使用 delete 时抛出 SyntaxError 有什么意义,如果属性不可配置,无论如何都会抛出 TypeError?这似乎是一个不必要的限制,在某些情况下,除了不使用严格模式(第三个示例)之外似乎没有任何解决方法。谁能解释一下这个决定背后的动机?


更新:我刚刚意识到我忽略了一个事实,即直接 eval 调用在严格模式下有自己的范围,而不是调用函数的范围,所以在第三个例子中 foo 不会在严格模式下定义。无论如何,运行时检查仍然会捕捉到这一点,但它提出了一个附带问题:是否没有办法在严格模式下拥有可配置的局部变量,就像我们在非严格模式下使用 eval 变量声明一样?据我所知,这是 eval 的少数合法用途之一。

最佳答案

你说的是Section 11.4.1, paragraph 5.a.规范:

  1. Else, ref is a Reference to an Environment Record binding, so
    a. If IsStrictReference(ref) is true, throw a SyntaxError exception.
    b. Let bindings be GetBase(ref).
    c. Return the result of calling the DeleteBinding concrete method of bindings, providing GetReferencedName(ref) as the argument.

你所谓的“不合格标识符”正式命名为“环境记录绑定(bind)”。

现在,回答你的问题。为什么在 5.c 时抛出 SyntaxError。无论如何都会失败?我想你自己回答了!

Strict mode must do a runtime check here, because a TypeError is thrown when this is encountered.

没错。但快速失败总是更好。因此,当有机会检测到 SyntaxError(在解析时)时,应该捕获这个机会。

为什么?如果发生错误,它可以避免您修复应用程序的麻烦。考虑一下可能会立即向您显示错误的 IDE,而不是数小时的调试。
此外,此类限制可能有利于优化的 JIT 编译器。

关于javascript - 删除不合格标识符时严格模式语法错误背后的动机?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10643587/

有关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 - 我可以使用 aws-sdk-ruby 在 AWS S3 上使用事务性文件删除/上传吗? - 2

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

  4. 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?

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

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

  6. ruby-on-rails - 如何从过时的 TZInfo 标识符中获取 Rails TimeZone 名称? - 2

    已经有一个问题回答了如何将“America/Los_Angeles”转换为“PacificTime(US&Canada)”。但是我想将“美国/太平洋”和其他过时的时区转换为RailsTimeZone。我无法在图书馆中找到任何可以帮助我完成此任务的东西。 最佳答案 来自RailsActiveSupport::TimeZonedocs:TheversionofTZInfobundledwithActiveSupportonlyincludesthedefinitionsnecessarytosupportthezonesdefinedb

  7. ruby-on-rails - 为什么在 Rails 5.1.1 中删除了 session 存储初始化程序 - 2

    我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于

  8. ruby - 如果它是标点符号,我怎么能从字符串中删除最后一个字符,在 ruby​​ 中? - 2

    啊,正则表达式有点困惑。我正在尝试删除字符串末尾所有可能的标点符号:ifstr[str.length-1]=='?'||str[str.length-1]=='.'||str[str.length-1]=='!'orstr[str.length-1]==','||str[str.length-1]==';'str.chomp!end我相信有更好的方法来做到这一点。有什么指点吗? 最佳答案 str.sub!(/[?.!,;]?$/,'')[?.!,;]-字符类。匹配这5个字符中的任何一个(注意,。在字符类中并不特殊)?-前一个字符或组

  9. 键删除后 ruby​​ 哈希内存泄漏 - 2

    你好,我无法成功如何在散列中删除key后释放内存。当我从哈希中删除键时,内存不会释放,也不会在手动调用GC.start后释放。当从Hash中删除键并且这些对象在某处泄漏时,这是预期的行为还是GC不释放内存?如何在Ruby中删除Hash中的键并在内存中取消分配它?例子:irb(main):001:0>`ps-orss=-p#{Process.pid}`.to_i=>4748irb(main):002:0>a={}=>{}irb(main):003:0>1000000.times{|i|a[i]="test#{i}"}=>1000000irb(main):004:0>`ps-orss=-p

  10. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

随机推荐