Возможно ли получить различную область для требуемого файла?

Предположим, что у меня есть файл примера 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);
two.one()
3 4

Но дублирование файла делает именно то, что я ищу.

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

Возможно ли это без изменения файла import.js или его дублирования?

Изменить:

Да, перезапись self в this будет работать, но это не то, что я прошу. Я хотел бы знать, можно ли восстановить другой масштаб. Настоящий файл import.js может содержать надежные объекты с рекурсивными вызовами, которые передаются через другие функции. Имея верхний уровень self, освобождает вас от любой необходимости или беспокойства о сфере видимости и привязке. Предполагая, что у вас сложный файл, и он всегда требуется один раз, но теперь для тестирования или того, что вы хотели бы импортировать дважды... Каковы другие варианты перекодирования вашей работы?

Ответ 1

По крайней мере, два способа его возможного....

(1) Удаление кеша

Как удалить модуль после "require" в 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) Использование функции Область

Поскольку требуется прочитать файл и затем запустить его,

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); })(); 

Я внутри файла теперь будет храниться внутри созданной вами области функций. поэтому еще раз:

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

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

Немного грязнее, но намного быстрее, чем удалять кеш и перечитывать файл каждый раз.

Ответ 2

Короче говоря, это невозможно сделать без изменения файла import.js или дублирования файла. Это связано с тем, что self является глобальной переменной для этого документа, которая будет одинаковой для каждого экземпляра объекта функции.

Альтернатива # 1

Проблема заключается в том, что вы назначаете self глобальной переменной. Оба они имеют доступ к одной и той же переменной, и поэтому вы получаете наблюдаемые результаты. Кроме того, ваше использование "я" не является необходимым. Ниже приведен код, описанный ниже.

function Test(a,b){
   this.a = a;
   this.b = b;
}
Test.prototype.run = function(){
   // Simply using 'this' to access the properties of the function is sufficient - no need for self
   console.log(this.a, this.b)
}
module.exports = Test

Рабочий пример

В этом случае с каждым экземпляром new Test() у вас будет отдельный экземпляр, поэтому вам не нужно будет "требовать" файлы.

Альтернатива # 2

Если вы хотите сохранить self в соответствии с вашим редактированием, другим вариантом будет просто переписать функцию, которую вы хотите вызвать. Например:

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

Test.prototype.run = function(){
   console.log(this.a, this.b)
}

Если это также не вариант, вам необходимо предоставить дополнительную информацию о том, что вы можете или не можете сделать.