微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

JavaScript 程序如何知道 ECMA-262 是否定义了全局属性名称?

如何解决JavaScript 程序如何知道 ECMA-262 是否定义了全局属性名称?

考虑一个名为 isEcmaGlobal 的假设函数,它为 ECMA-262 全局变量的字符串名称返回 true

$ node
> isEcmaGlobal('Array')
true
> isEcmaGlobal('process')
false

如何设计这个功能

解决方法

这里要小心。在这个答案有意义之前,我们需要问另一个问题:我们是按照 ECMA-262(“标准”)现在的规定对全局变量进行分类,还是按照管理我们程序运行时的标准?

换句话说:多台机器应该看到相同的答案吗?

按照现行标准

假设我们希望 isEcmaGlobal 返回 true 就标准所说的现在。我不会在这里展示任何代码,因为如果您关心此类问题,那么您可能已经考虑过下载或抓取标准全局名称。

按照当前运行时

现在假设我们希望 isEcmaGlobal 根据当前运行时中可用的离线信息返回 true。这并不像遍历全局对象的“自己的”属性名称并根据硬编码数组(如 ['Array','Object',...])检查它们那么容易。如果我们这样做了,那么我们就必须验证我们的数组是否正确。我们无法验证硬编码数据,因为它假定 isEcmaGlobal 已经为那个确切的运行时间编写了!我们无法粘贴 ECMA-262 中的全局名称,因为我们不知道该文档的版本是否与运行时相同。我们也无法检查互联网,因为我们假设了一个离线解决方案。

所以我们不能硬编码,但我们可以尝试其他的东西。我将使用 Node.js v14.16.0 及其内置的 vm 模块。该程序利用 vm 在新评估器中提供标准全局变量的需要。我们告诉 vm 使用空的全局对象评估代码,但该全局对象不会为空。

const vm = require('vm');

function isEcmaGlobal(identifier) {
  try {
    // Lol,what security?
    vm.runInContext(identifier,vm.createContext({}))
    return true;
  } catch (e) {
    return false;
  }
}

这里有几件事。

首先,警告:为了说明和简洁,本示例使用未消毒的代码执行。不要为了走捷径而把它放在剪贴板上。

其次,您可以看到我们的目标是创建一个仅定义标准全局变量的新评估器,并且无法了解评估器外部发生的情况(eval 不执行上述任何一项操作)。如果我们找到了评估员,那么您只需将 Object.getOwnPropertyNames(new Function('return this')()) 扔进去,我们就可以回家了。

但是我们正在做一个谓词,所以假设“精益”全局对象是正确的,评估将抛出一个 ReferenceError 非标准标识符。

不幸的是,有些事情是不对的。

> isEcmaGlobal('Array')
true
> isEcmaGlobal('process')
false // yes!
> isEcmaGlobal('global')
false // yes!!
> isEcmaGlobal('console')
true  // no!!!

该死,出于某种原因,我们仍然有一个 Node 全局变量。所以在这一点上你可以说我把这一切都变得太复杂了,因为 Node.js 没有添加那么多全局变量,或者我错过了一个配置选项或现有的谓词。你在所有方面都是对的,但这错过了问题的重点。问题以“JavaScript 程序 能知道……吗?”开头,我使用 Node 是为了说明一种解决问题的方法,无需硬编码标准全局名称并产生矛盾。即使 Node.js 只添加了一个非标准的全局变量,如果我们不能得到一个干净的评估器,问题仍然存在。

回顾

要在 某些 JavaScript 运行时中实现 isEcmaGlobal,该运行时需要为您提供一种方法来运行 bare-bones JS 评估器,无需任何主机- 特定的扩展。 eval 不算。使其只接受标识符,然后评估这些标识符。将异常解释为返回 false 的原因。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?