问题描述
今天,我遇到了一个问题,即 top
是一个预先存在的全局变量.
Today I ran into an issue that top
is a pre-existing global variable.
const left = 1;
const right = 2;
const top = 3;
const bottom = 4;
console.log(left, right, top, bottom);
结果:
Uncaught SyntaxError: Identifier 'top' has already been declared
我想直到今天,我大多数时候对变量 top
的使用都在函数内部.
I think I've just been lucky until today that most of the time my usage of a variable called top
was inside a function.
我需要为浏览器添加新的全局变量而担心,这些变量将来会破坏代码吗?直到es6导入,几乎所有浏览器库似乎都使用了全局变量,除非它们具有构建步骤.但是,查看 top
示例,似乎浏览器可以随时添加新的无法设置的全局变量,因此应不惜一切代价避免使用它们.我看到诸如 HTMLElement
之类的一些变量是可分配的.
How much do I need to worry about browsers adding new global variables that will break code in the future? It seems like until es6 import pretty much all browser libraries used global variables unless they had a build step. But, looking at the top
example it seems like browser could add new unsettable global variables at anytime and therefore they should be avoided at all costs. I see some variables things like HTMLElement
are assignable.
console.log(HTMLElement);
HTMLElement = 'foo';
console.log(HTMLElement);
结果:
function HTMLElement() { [native code] }
foo
top
是否有些遗留问题,但是浏览器规格承诺将来不会做更多的事情?就像我无法分配 window
Is top
some legacy thing but browser specs promise not to do more of that in the future? Like I can't assign window
const window = 'foo';
console.log(window);
结果:
SyntaxError: Identifier 'window' has already been declared
但是我可以在节点中分配 process
but I can assign process
in node
Welcome to Node.js v12.6.0.
Type ".help" for more information.
> process
process {
version: 'v12.6.0',
versions: {
node: '12.6.0',
...
}
> process = 'foo'
'foo'
> process
'foo'
>
推荐答案
您不必为此担心.JS和HTML的新功能已经过广泛测试.浏览器通常会部署代码,以监视与计划的API的不兼容性,以确定它们是否可以安全运输.(例如,如果浏览器想要添加 globalThis.foo
,则它可能会部署一个计数器,该计数器在每次访问或分配给 globalThis.foo
的代码时都会递增,以了解是否已经在用于其他东西).此外,浏览器的开发人员预览版可让开发人员在可能的问题解决之前,先将其发现.您可能会发现这很有趣: https://developers.google.com/web/更新/2018/03/smooshgate .
You shouldn't worry about it. New features for JS and HTML are tested extensively. Browsers will generally deploy code that watches for incompatibilities with planned APIs to determine if they will be safe to ship. (For example if a browser wants to add globalThis.foo
, it might deploy a counter that increments every time code accesses or assigns to globalThis.foo
to understand if it's already being used for something else). In addition, developer previews of browsers allow developers to catch possible issues before they get too far. You might find this interesting: https://developers.google.com/web/updates/2018/03/smooshgate.
说了这么多,我仍然不建议您去创建很多全局变量,这不是最奇妙的模式.
All that being said, I still wouldn't suggest you go around creating lots of globals, it's not the most fantastic pattern.
这确实是遗产,尽管我不知道有任何这样的承诺.HTML标准对 window.top
的定义如下(来自 https://html.spec.whatwg.org/#the-window-object ):
It is indeed legacy, though I don't know of any such promises. The HTML standard defines window.top
as follows (from https://html.spec.whatwg.org/#the-window-object):
[LegacyUnforgeable] readonly attribute WindowProxy? top;
[LegacyUnforgeable]
表示属性 top
是在 window
上创建的,并且属性 configurable
设置为 false
.遮盖不可配置属性的全局声明将失败,因为它们无法更改值.
[LegacyUnforgeable]
means the property top
is created on window
with the property attribute configurable
set to false
. Global declarations that shadow non-configurable properties will fail because they cannot change the value.
这是因为Node.js中的 process
是可配置的属性.
This is because process
in Node.js is a configurable property.
> Object.getOwnPropertyDescriptor(globalThis, 'process')
{
get: [Function: get],
set: [Function: set],
enumerable: false,
configurable: true
}
最后一点,赋值和声明之间是有区别的.您仍然可以分配不可配置的属性,只要它们是可写的或提供设置器即可.
As a last note, there is a difference between assignments and declarations. You can still assign to non-configurable properties as long as they are writable or provide a setter.
这篇关于有关全局变量/全局名称空间的JavaScript策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!