Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/393.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 什么是';全局符号注册表';?_Javascript_Ecmascript 6_Symbols - Fatal编程技术网

Javascript 什么是';全局符号注册表';?

Javascript 什么是';全局符号注册表';?,javascript,ecmascript-6,symbols,Javascript,Ecmascript 6,Symbols,是窗口['sym'],它已经是全局范围 但是他说: 使用Symbol()函数的上述语法不会创建在整个代码库中可用的全局符号。要创建跨文件和在全局范围(如环境)中可用的符号,请使用方法Symbol.for()和Symbol.keyFor()从全局符号注册表中设置和检索符号 sym已在浏览器的全局范围内,具有上述声明语法 什么是全球符号注册 每个html文档都与窗口对象绑定 所以, 在浏览器世界中,跨文件/领域的符号可用性范围与全局范围(窗口对象)有何不同?全局符号注册表只是符号实例的方便全局存储库

窗口['sym']
,它已经是全局范围

但是他说:

使用
Symbol()
函数的上述语法不会创建在整个代码库中可用的全局符号。要创建跨文件和在全局范围(如环境)中可用的符号,请使用方法
Symbol.for()
Symbol.keyFor()
从全局符号注册表中设置和检索符号

sym
已在浏览器的全局范围内,具有上述声明语法

什么是全球符号注册

每个html文档都与
窗口
对象绑定

所以,
在浏览器世界中,跨文件/领域的符号可用性范围与全局范围(
窗口
对象)有何不同?

全局符号注册表只是符号实例的方便全局存储库。如果愿意的话,您可以自己实现一个,但是拥有这样一个内置的存储库意味着运行时可以将其用作发布符号实例的场所,这些符号实例对于给定的上下文具有特定的意义

在您自己的应用程序中,您可以决定某些类型的对象将具有通过某些符号可访问的某些属性。所有代码都可以通过
Symbol.for()
找到这些符号:

因为注册表是全局的,所以无论作用域或编译单元如何,它都可以工作

通过使注册表成为运行时的一部分,Node.js这样的环境可以使用符号机制来扩展对象,而不用担心会给遗留代码带来问题。比如,如果Node想让您知道一个对象使用了多少内存,他们可以发明一个符号,将其放入注册表,并记录注册表项。任何代码都可以使用:

var SPECIAL_PROPERTY = Symbol.for("mySpecialProperty");
// ...
var specialVal = someObject[SPECIAL_PROPERTY];
(这完全是编造出来的;节点做那个特定的事情可能毫无意义。)由于符号作为属性键的工作方式,如果它所操纵的对象突然开始携带额外的属性,不知道的代码不会遇到任何奇怪的问题

(当然,符号注册表本身的名称空间只是一个名称空间,因此冲突的处理方式与我们在
窗口中处理名称冲突的方式几乎完全相同。)

正在字典(
window
)中创建一个新属性
sym
,该属性位于全局范围内,可以通过
window['sym']
访问该属性的值

不,它确实创建了一个符号并将其分配给名为
sym
的局部变量。只有当您在全局范围内执行此代码时(对于模块化,您通常不会这样做),它才会在您的领域(js环境)的全局对象上创建属性。请注意,这个全局对象并不总是像网页中的窗口一样,它取决于您的环境

什么是全球符号注册

它是一个可以通过字符串键访问的符号注册表(想想:字典)。在这种情况下,“全局”意味着比全局范围更全局,全局符号注册表确实跨越了引擎的所有领域。在浏览器中,网页、iframe和web worker都有自己的领域和自己的全局对象,但它们可以通过这个全局注册表共享符号

而这种分享正是目的所在。如果你不这样做的话

var sym = Symbol();
在两个位置,然后
sym1!==sym2
。如果您有一个共享对象,使用符号作为属性键将创建两个不同的属性。不管你怎么做

var sym1 = Symbol("shared");

var sym2 = Symbol("shared");
然后
sym1===sym2
当您使用它时,您将始终获得相同的属性


有关更多示例,请参见和,包括类似全局的已知符号。

全局符号注册表存在于窗口中的所有iFrame中。(由于符号不能在工人之间传递,因此,除非存在旁道检查(如通过检查),否则没有可观察到的在工人之间相同的概念。)

。并保留对
obj
的引用


事实上,由于javascript不提供API来删除全局注册表中的符号,如果您需要手动管理注册表内存,则使用手动缓存方式是有益的。

那么您的问题是,为什么创建全局变量会使其成为全局变量,即使全局变量的值是一个符号?@overexchange“实际值”是什么意思?你的期望是什么,这是非常不清楚的
sym
是值,没有其他显示。loganfsmyth,这是关于某个链接问题的,忽略它。另请参见全局范围位于
窗口
对象级别。如果一个html文件通过脚本标记包含多个.js文件。由多个.js文件创建的环境位于同一个
窗口
对象下。我说得对吗?当你说跨文件(整个代码库)时,我们谈论的是哪个范围?我仍然不清楚。@overexchange它在浏览器的
窗口
对象级别。还有一些JavaScript环境没有
窗口
对象。但是,是的,网页上下文中的所有JavaScript代码都可以访问相同的
窗口
对象。全局符号注册表的作用域与全局
symbol()
函数本身的作用域完全相同。JS引擎中的*global symbol registry*(GSR)是否与
window
对象在物理上不同?如果GSR与
window
对象的作用域相同,那么我们为什么需要GSR?另外,在大多数模块化JS代码(包括节点)中,文件的顶级作用域是模块作用域,而不是全局作用域,因此您的
var sym
示例不是全局的。GlobalSymbolRegistry(GSR)与
window
对象在物理上不同吗?当浏览器的JS引擎维护
window
object时,谁维护GSR?@overexchange:是的,它
var sym = Symbol();
var sym1 = Symbol("shared");

var sym2 = Symbol("shared");
var sym1 = Symbol.for("shared");

var sym2 = Symbol.for("shared");
<script>
document.head.appendChild(document.createElement('iframe'))
.src=`javascript:
  alert(parent.Symbol===Symbol) /*false*/
  ,alert(parent.Symbol.for('a') === Symbol.for('a')) //true
`
</script>
obj['a']? obj['a'] : obj['a'] = Symbol()