Возможно ли получить различную область для требуемого файла?
Предположим, что у меня есть файл примера 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)
}
Если это также не вариант, вам необходимо предоставить дополнительную информацию о том, что вы можете или не можете сделать.