有关全局变量/全局名称空间的JavaScript策略 [英] JavaScript policy on global variables / the global namespace

查看:53
本文介绍了有关全局变量/全局名称空间的JavaScript策略的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我遇到了一个问题,即 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'
> 

推荐答案

我需要担心浏览器添加新的全局变量,这些变量将来会破坏代码吗?

How much do I need to worry about browsers adding new global variables that will break code in the future?

您不必为此担心.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.

最重要的是一些遗留的东西,但是浏览器规格承诺将来不会做更多的事情吗?就像我无法分配窗口一样

Is top some legacy thing but browser specs promise not to do more of that in the future? Like I can't assign window

这确实是遗产,尽管我不知道有任何这样的承诺.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.

但是我可以在节点中分配进程

but I can assign process in node

这是因为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策略的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆