javascript - 从根本上说,对全局范围本身的本地引用是一个坏主意吗?

标签 javascript global

如果这是一个愚蠢的问题,请原谅我的无知或偏执,但我似乎无法在这种特定情况下找到任何东西(这让我认为也许大多数人要么知道避免它,要么有更好的方法来处理这个问题)。
前提是:我不知道我的代码是否一定会始终在浏览器中运行,因此,我不知道我是否可以访问 window (特别是那个名字)或者如果这个范围在我的代码可能发现的任何环境中被命名为其他东西。
所以我的想法是找到该范围一次,将其分配给一个局部变量,然后让我的函数中的所有内容都只引用该局部变量,如果我需要访问全局范围而不是到达 window (同样,它可以被称为别的东西——我不知道)。
我担心的是,这是否会导致一些内存泄漏问题(或者由于其他原因可能是个坏主意)?有什么我应该注意的或者我可以去吗?

function myConstructor() {
    // Is this fundamentally a bad idea?
    var globalScope = findGlobalScope() // Cyclic reference here?

    function findGlobalScope() {
        // Let's say I had some logic here that
        // determinded that I'm running this code
        // in a browser, so now I know `window`
        // is where my global variables are.
        // Keep in mind it may not always be `window`,
        // but let's say this time it is.
        return window
    }

    this.doWork = function() {
        // In here I reference the `globalScope` variable
        // instead of the `window` variable explicitly.
        // 
        // I'm doing it this way because I don't want
        // my code to break if I run it outside of a browser
        // where I might not have access to an object explicitly
        // named "window"
        console.log(globalScope) // instead of console.log(window)
    }
}

var myObj = new myConstructor()

// Now `myObj` is located at `window.myObj`
// and `myObj` has a reference to `window`
// which... again, has a reference to window.myObj
// Is this something I should be concerned about?
我很感激帮助。

最佳答案

它不是一个范围,它是一个对象。 (但您可以将其视为一个范围,这是可以理解的;它被其中一个全局范围用于保存变量。¹)
这绝对没问题,它不会导致泄漏或任何事情。这是一个您知道不会消失的对象(除非您的代码也这样做)。
请注意,JavaScript 现在有 globalThis ,这正是您正在寻找的。 :-) 这是一个相对较新的添加。

也就是说,as Taplar mentioned ,理想情况下,您的代码不应该关心全局对象,并且应该尽可能避免完全创建全局变量。全局命名空间很拥挤——和 非常挤在浏览器上。
避免使用全局范围的方法:

  • 使用模块。现代环境支持 ES2015 的模块。可以通过 Webpack 或 Rollup.js 等捆绑程序支持较旧的环境。
  • 如果您不能使用模块,请使用包装函数。如有必要,因为您的代码必须在运行时跨文件拆分,请让该函数公开一个名称晦涩的全局变量,该全局变量在其上具有用于其他事物的属性。

  • #2 的示例(使用 ES5 语法):
    var myStuff = myStuff || {};
    (function() {
        myStuff.doSomething = function() {
           // ...
        };
    })();
    

    ¹ 这是 JavaScript 的一个有趣但令人困惑的部分:JavaScript 中至少有两个全局作用域,一个是外部作用域,一个是内部作用域(这是 ES2015+ 中的新功能)。
    外部的“变量”是全局对象的属性,可以是继承的,也可以是自己的属性:如果您使用变量名称,并且它不存在于当前范围或当前范围和全局范围之间,但确实作为全局对象上的属性存在,使用全局对象上的属性——旧式全局变量。当你在全局范围内声明一个函数,或者用 var 声明一个变量时,它将一个属性添加到全局对象。全局对象也(在大多数环境中)从其原型(prototype)及其原型(prototype)的原型(prototype)继承事物。例如,在浏览器上为带有 id 的元素创建的全局变量是 WindowProperties 对象的属性,它位于全局对象的原型(prototype)链中。它有时还具有其他“自己的”属性,例如 name (浏览器上的窗口名称)。
    内部全局范围不使用全局对象。这是用 let 声明的东西的地方, const , 和 class去。它们不会成为全局对象的属性。

    关于javascript - 从根本上说,对全局范围本身的本地引用是一个坏主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63707878/

    相关文章:

    javascript - 我如何使用R htmlwidgets在jupyter笔记本中显示javascript可点击按钮

    javascript - 如何检查窗口是否从 window.open() 实例化

    nginx - 如何使用Digital Ocean DNS和Nginx设置全局负载平衡?

    c++ - 在 OpenMP 中使用私有(private)版本的全局外部变量

    javascript - 为什么全局变量被认为是不好的做法?

    javascript - Highcharts,向情节线添加图标?

    Javascript:自动化功能

    php - Codeigniter 当我单击删除时,如果单击是或否,我想弹出通知

    c - 从函数访问全局指针时出现段错误

    objective-c - 创建全局 "null"结构以在 C 程序中重用?