Javascript 如何从构造函数调用全局变量

Javascript 如何从构造函数调用全局变量,javascript,node.js,mocha.js,Javascript,Node.js,Mocha.js,我有一个类似这样的类: class-MyClass{ 构造函数(){ 该字段=42; } 方法(){ 返回“你好,世界!”; } } 我想将它的一个实例定义为全局变量,所以我注册了它: global.MyObject=newMyClass(); 这意味着这将起作用: console.log(MyObject.field);//42 console.log(MyObject.method());//你好,世界! 然而,每当我从另一个类调用相同的代码时,它突然变得更加随机: class-Oth

我有一个类似这样的类:

class-MyClass{
构造函数(){
该字段=42;
}
方法(){
返回“你好,世界!”;
}
}
我想将它的一个实例定义为全局变量,所以我注册了它:

global.MyObject=newMyClass();
这意味着这将起作用:

console.log(MyObject.field);//42
console.log(MyObject.method());//你好,世界!
然而,每当我从另一个类调用相同的代码时,它突然变得更加随机:

class-OtherClass{
构造函数(){
console.log(MyObject.field);//未定义
console.log(MyObject.method());//类型错误:MyObject.method不是函数
}
}
有时候这样行,有时候不行。我不知道它什么时候起作用,什么时候不起作用,只是它不是完全随机的。从同一个地方调用,构造函数要么工作,要么不工作。这无助于隔离问题

似乎当类的构造函数从没有直接的
require('my-class')
的模块调用时,它将不起作用-即使
OtherClass
有这个requirement?即使其他模块都有
所需的
?这毫无意义

我用两个模块A和B进行了尝试。如果A定义了全局变量,B可以很好地访问它们,即使没有
require
——只要其他人有

所以。。。我对这是怎么回事感到困惑。可能是一个愚蠢的JavaScript噱头,我不是本地JavaScript开发人员

我的设置如下所示:

  • src/
    • 实际代码(使用将创建其他类的功能)
  • 试验/
    • 嘲弄/
      • 我的班级
      • 其他类(
        require('MyClass')
    • 实际检查(
      require('ActualCode')
      require('OtherClass')
当从
MyClass
OtherClass
调用时,
OtherClass
中的构造函数将能够访问
MyClass
,但不能从
ActualCode
actualdetest
。即使按顺序调用(因此全局变量肯定存在)

这意味着更改参数和添加
require
是不可能的,因为
实际代码不应该知道测试代码

问题似乎出在Mocha框架上。无法在“it”中访问全局变量:

console.log(MyObject.field);//42
它('test',()=>{
console.log(MyObject.field);//未定义
}
如果我删除周围的代码,它(显然)会工作


如何从类的构造函数调用全局变量?

当您将所有变量都放在一个文件中时,此示例代码可以正常工作:

$ cat sample.js 
class MyClass {
    constructor() {
        this.field = 42;
    }

    method() {
        return "Hello world!";
    }
}
global.MyObject = new MyClass();

class OtherClass {
    constructor(props) {
        console.log(MyObject.field);
        console.log(MyObject.method());
    }
}

new OtherClass();
$ node sample
42
Hello world!

我怀疑在加载模块时,这些行的运行顺序可能会产生混淆。节点的模块加载代码将按照遇到的顺序运行每一行。

您似乎想要一个:一个全局只存在一个共享实例的类。请注意,单例通常被认为是一种反模式ern,并且应该被视为系统耦合过于紧密的标志

但是,这是您可以为您的用例实现它的方式(假设您使用node>=
13.2.0
作为ES6
export
语法)

然后可以通过从其他模块导入并调用
getMyClassInstance()
来获取该实例

import {getMyClassInstance} from './MyClass',
class OtherClass {
    constructor(props) {
        const MyObject = getMyClassInstance();
        console.log(MyObject.field);
        console.log(MyObject.method());
    }
}

(只要你不导出代码> MyClass <代码>,你可以认为它是一个单体,但是从你的问题中,你的模块是如何被加载和相互关联的还不完全清楚。根据你的配置,你可能需要在私有的构造函数中封装<代码> MyClass <代码>,以便它严格地成为一个。问题是摩卡在测试中无法访问全局变量。我找不到全局变量 此行为的相关bug,但至少有一个

由于全局变量仅在测试中使用,因此我得到了一个简单的解决方案:

global.MyObject=newMyClass();
module.exports.MyObject=MyObject;
在测试中:

之前(()=>{
global.MyObject=require('./mock/my class').MyObject;
});

添加一个ToDo可能是一个好主意,这样你就可以经常访问这个问题,以防MOCA人员修复它。

什么是<代码>全局< /代码>?是这个节点吗?如果是这样的话,让你的代码更便携,你可以考虑使用<代码> Global THE/<代码>。然后你会做<代码> Global To.MyObjor。无论如何,我不会这样做全局变量,而是使用模块。不要使用全局变量。但是,如果你真的真的真的想破坏你的程序安全并使其难以推理,什么是
globals
——你在NodeJS上吗?如果是,请将其标记为这样。如果类构造函数依赖于一段数据,为什么不使用参数?@ggorlen My代码是针对(和内部)复杂的JavaScript应用程序(不是我的)运行的。为了测试这段代码,我正在创建模拟代码。因为“复杂的JavaScript应用程序”使用全局变量,我的mock也需要这样做。因此,使用参数是不可能的,因为任何不会将字段放入
MyObject.field
。提供上下文是很好的,谢谢,但我怀疑访问是否有效是一个掷硬币的问题。没有参数,除了猜测发生了什么以外,很难做更多的事情。不要这样做在JavaScript中,将所有代码放在同一个文件中是一个好主意?全局变量的定义在任何一个类之前运行,这很容易检查。不,绝对不是!但正如其他人所指出的,使用
global
作为存储内容的地方也不是一个好主意。我的答案只是演示一下那
import {getMyClassInstance} from './MyClass',
class OtherClass {
    constructor(props) {
        const MyObject = getMyClassInstance();
        console.log(MyObject.field);
        console.log(MyObject.method());
    }
}