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
作为ES6export
语法)
然后可以通过从其他模块导入并调用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());
}
}