我有一个javascript文件,其中我需要另一个文件,该文件的变量会发生变化。
main.js
let num = require("./extra").num
extra.js
let num = 5;
setInterval(() => {
if (num > 0) {
num--;
}
console.log(num);
}, 1000);
module.exports = {
num
};
现在在main.js文件中,变量num始终为5,并且永不更改。我需要怎么做才能使其始终保持更新?
注意:在变量更改后,我要在main.js中声明该变量,因此它不应为5
答案 0 :(得分:0)
require()
在main.js
开始运行时(即在第一个setInterval()
触发器之前)进行评估,因此require("./extra").num
始终返回5
。
此外,由于num
是通过module.exports
中的值传递的,因此重复调用require()
不会有帮助。
一种可行的(不确定最好的方法)是:
let num = 5;
setInterval(() => {
if (num > 0) {
num--;
}
console.log(num);
}, 1000);
function getNum() {
return num;
}
module.exports = {
getNum
};
然后
let num = require("./extra").getNum()
答案 1 :(得分:0)
这将起作用:
在extra.js
中:
let num = 5;
setInterval(() => {
if (num > 0) {
num--;
}
console.log("in extra: " + num);
}, 1000);
module.exports = {
getNum: function() {
return num;
}
};
在main.js
中:
let num = require('./extra').getNum();
console.log("initial value is: " + num);
setInterval(() => {
let num = require('./extra').getNum();
console.log("in main loop: " + num);
}, 1000);
由于main.js
中的打印语句每秒输出一次,因此您会注意到require('./extra').getNum()
的每个新调用都会获得新的递减值。
答案 2 :(得分:0)
关于此问题的另一种观点:将信息存储在变量中并传递给变量时,您正在处理“值”和“引用”之间的差异。
原语按值(字符串,数字,布尔值)传递。 更复杂的结构通过引用(对象,数组,函数)传递。
有什么区别?
按值传递:
let a = 3
let b = a
console.log(a) // 3
console.log(b) // 3
a = 4
console.log(a) // 4 (obviously)
console.log(b) // 3 (when we assigned b = a, b was assigned to the value of a, which at the time was 3)
在此示例中,b
并不继承赋值期间的所有属性(var b = a
),仅继承其值。这实质上就是您发布的代码中发生的事情。由于num是基元,因此当您为其分配值时,仅传递其值 。这实际上发生在两个地方:
module.exports = {
num
}
和
let num = require("./extra").num
在这两种情况下,都声明了一个变量(或在module.exports中进行了重新分配,并为其分配了num
的值,这是一个原始值。现在,这些变量和/或对象属性已“锁定在“可以这么说,除非在代码中的其他位置手动将它们重新分配为其他值。
通过引用传递:
我在上面所说的“复杂结构”,就像一个对象,实际上(以一种简单的陈述方式)是指向内存中某个位置的指针,该位置包含对其他对象的引用值(又称属性/方法)。如果听起来很抽象,那是因为。每次创建对象时,JavaScript引擎都会在内存中保留另一个位置,以收集和引用该对象的属性。这会创建一些有趣的场景,例如:
const a = {}
const b = {}
console.log(a === b) // false!
console.log(a == b) // also false!
即使我们查看了这些对象并说它们看起来是相同/相等的,它们实际上都是对内存中位置的引用,而在内存中是两个不同位置,因此它们不能相同。但是,如果我们将两个变量都分配到内存中的同一位置,它们将总是相等(这里是您问题的解决方案):
const a = {}
const b = a
console.log(a === b) // true!
console.log(a == b) // also true!
a.prop = 4
console.log(b) // { prop: 4 }
b.prop = 2
b.other = 3
console.log(a) // { prop: 2, other: 3 }
如您所见,既然两个变量都指向内存中的相同位置(const b = a
),它们将始终“共享”相同的属性,因此,这些属性的值相同。
我希望这会有所帮助,这是解决您原来问题的以下原理的一种实现方式(可能不建议其他人推荐的单例“ getNum”选项,但肯定同样可行):
index.js
const obj = require('./num')
console.log(obj.num)
setTimeout(() => console.log(obj.num), 2000)
setTimeout(() => console.log(obj.num), 4000)
setTimeout(() => console.log(obj.num), 6000)
num.js
const obj = { num: 5 }
setInterval(() => {
if (obj.num > 0) {
obj.num--
}
}, 1000)
module.exports = obj
祝您编程愉快!
答案 3 :(得分:0)
您不能使用简单的整数值来执行此操作,因为它作为值而不是作为引用传递。但是你可以用一个对象来代替
main.js
let num = require("./extra").num
setInterval(function(){
console.log(num.value); // print 1, 2, 3
}, 1000);
额外的.js
module.exports.num = {value: 0};
setInterval(function(){
exports.num.value++;
}, 1000);
答案 4 :(得分:0)
做一个不同的答案。如果您想保留 num
而不是 getNum()
,您可以使用带有 setter 和 getter 的类来表示 num
。例如:
extra.js
module.exports = new class ExtraContainer {
constructor() {
this._num = 5;
// Do stuff...
setInterval(() => {
if (this._num > 0) {
--this._num;
}
// console.log(this._num);
}, 1000);
}
get num() {
return this._num;
}
set num(value) {
// Do nothing...
}
}
index.js
const extra = require("./extra");
console.log(extra.num);
// 2 sec timeout
setTimeout(() => {
console.log(extra.num);
}, 2000);
// 5 sec timeout
setTimeout(() => {
extra.num = 1000; // The user cant modify the variable
console.log(extra.num);
}, 6000);
// 7 sec timeout
setTimeout(() => {
extra._num = 1000; // You can avoid this with diff teqniques
console.log(extra.num);
}, 7000);
输出
5
3
0
1000
警告:您不会破坏 setInterval
,因此您的代码永远不会结束。