javascript - 是否可以为所需文件获得不同的范围?

标签 javascript node.js scope closures

假设我有这个名为 import.js 的示例文件

var self;
function Test(a,b){
   this.a = a;
   this.b = b;
   self = this;
}
Test.prototype.run = function(){
   console.log(self.a, self.b)
}
module.exports = Test

当我需要文件并创建一个新的“对象”时,一切正常,但是当我创建第二个对象时,它们都可以访问自身,只有后者有效。

var Test = require('./import.js');

var one = new Test(1,2);
one.run()
1 2

var two = new Test(3,4);
two.run()
3 4
one.run()
3 4

有没有办法重新要求文件以创建单独的范围?

把它当作两个不同的变量是行不通的,

var Test1 = require('./import')
var Test2 = require('./import')
var one = new Test1(1,2);
var two = new Test2(3,4);
one.run()
3 4

但是复制文件正是我想要的..

var Test1 = require('./import1');
var Test2 = require('./import2');
var one = new Test1(1,2);
var two = new Test2(3,4);
one.run();
1 2

是的,将 self 重写到 this 中是可行的,但是,这是否可能不修改或复制 import.js 文件?

最佳答案

在这里回答我自己的问题,但至少有两种可能的方法......

(1) 删除缓存

How to remove module after "require" in node.js?

var Test1 = require('./import.js');
delete require.cache[require.resolve('./import.js')]
var Test2 = require('./import.js');

var one = new Test1(1,2);
var two = new Test2(3,4);

one.run()
1 2
two.run()
3 4

甚至看起来都没有那么乱,虽然它非常低效,而且以这种方式编写代码会很快变得成本高昂...


(2) 使用函数作用域

因为require读取文件然后运行,

var Test = require('./test.js');

相当于

var Test = eval( fs.readFileSync('./test.js', 'utf8') );

因此,如果您不使用 require,而是阅读文件,您可以在函数内部建立新的作用域:

var fs = require('fs');
var File = fs.readFileSync('./import.js', 'utf8');
var Test1, Test2;
(function(){ Test1 = eval(File); })();
(function(){ Test2 = eval(File); })(); 

文件中的 self 现在将存储在您创建的函数范围内。所以再一次:

var one = new Test1(1,2);
var two = new Test2(3,4);

one.run()
1 2
two.run()
3 4

稍微困惑一些,但比每次删除缓存并重新读取文件要快得多。

关于javascript - 是否可以为所需文件获得不同的范围?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42376161/

相关文章:

javascript - 这个表单元素叫什么以及如何做

node.js - 为什么 sails.js 的真实电子邮件地址验证失败

javascript - 错误: Can't set headers after they are sent from a forEach loop

c# - 从 if/else 语句中获取值?

C# 函数 : access local variables in a block

javascript - 如何检查评估名称是否未定义

Javascript基于数组创建动态变量

C# tostring(基数)

c++ - C++变量销毁

node.js - StrongLoop 的 LoopBack.io : How to turn on HTTP access log?