web-dev-qa-db-ja.com

複数のファイルで変数を共有および変更するnode.js

main.js

var count = 1;

// psuedocode
// if (words typed begins with @add)
require('./add.js');

// if (words typed begins with @remove)
require('./remove.js');

// if (words typed begins with @total)
require('./total.js');



module.exports.count = count;

total.js

var count = require('./main.js').count;
console.log(count);

add.js

var count = require('./main.js').count;
count += 10;
console.log(count);

remove.js

var count = require('./main.js').count;
count -= 10;
console.log(count);

console.log

 1
 11
 -9

バックグラウンド:

アプリケーション(ircボット)があり、peepsが@add 1または@remove 1を実行できる機能を追加します。その後、言われたトリガーに応じて異なるファイルを必要とするmain.jsがあります。したがって、addはadd.jsファイルをトリガーし、それからrequire( 'main.js')に10(単純化のために10、実際に数値を解析してその数値を使用します)を追加します。私が抱えている問題は、誰かが@removeを実行することです。 require( 'main.js')し、1から10を引いて-9になります。 @totalを実行すると、1が出力されます。

Module.exportsについてはかなり良い検索を行いましたが、上記のような例に出くわしていません。 ドキュメント 私がやりたいことに近い例は含めないでください。そして、これらの質問 12 私は理解しています-しかし、私にとっては何の有用性もありません-私はそこで言われていることを理解しています。

質問:

@addと@removeの両方に同じ変数(count)を操作させ、@ totalが@addと@removesを考慮してcountの合計を返すようにします。 module.exportsを間違って使用していますか?または、1つのファイルでmodule.exportsの内容を変更し、結果をmain.jsファイルに返すことで、変数を共有する一般的な方法がありますか?

36
thtsigma

問題は、var count = require('./main.js').count;を実行すると、参照ではなくその番号のコピーが取得されることです。 countを変更しても、「ソース」は変更されません。

ただし、ファイルのエクスポート機能が必要です。ファイルを要求すると最初に実行されるだけですが、その後はキャッシュされ、再実行されません。 ドキュメントを参照

提案#1:

// main.js
var count = 1;
var add = require('./add.js');
count = add(count);

// add.js
module.exports = function add(count) {
    return count+10;
}

#2:

var count = 1;
var add = function() {
    count += 10;
}
add();

#3:個人的にはカウンターモジュールを作成します(これは単一のインスタンスですが、簡単に「クラス」にすることができます):

// main.js
var counter = require('./counter.js');
counter.add();
console.log(counter.count);

// counter.js
var Counter = module.exports = {
    count: 1,
    add: function() {
        Counter.count += 10;
    },
    remove: function() {
        Counter.count += 10;
    }
}
51
MiniGod

これが新しいかどうかはわかりませんが、実際にファイル間で変数を共有できます:

main.js

exports.main = {
    facebook: null
};

counter.js

var jamie = require('./main'); 
console.info(jamie); //{facebook: null}
jamie.main.facebook = false;
console.info(jamie); //{facebook: false}

anothercheck.js

var jamie = require('./main'); 
console.info(jamie); //{facebook: null} //values aren't updated when importing from the same file.
jamie.main.facebook = true;
console.info(jamie); //{facebook: true}

これで、ファイル間で共有できます。

13
Jamie Hutber

私はあなたと同じ問題を抱えています。 node.jsスクリプトで異なるフォルダー/ファイルにあるコントローラー、関数、モデルを分離し、コードを簡単に管理できるようにします。

これが最善の解決策かどうかはわかりませんが、あなたのニーズに合うことを願っています。

models/data.js

// exports empty array
module.exports = [];

controllers/somecontroller.js

var myVar = require('../models/data');
myVar.Push({name: 'Alex', age: 20});
console.log(myVar);
//  [{ name: 'Alex', age: 20 }]

controllers/anotherController.js

var myVar = require('../models/data');

console.log(myVar);
// This array has value set from somecontroller.js before...
//  [{ name: 'Alex', age: 20 }]

// Put new value to array
myVar.Push({name: 'John', age: 17});
console.log(myVar);
// Value will be added to an array
//  [{ name: 'Alex', age: 20 }, { name: 'John', age: 17}]
4

異なるファイル間で参照を共有する方法はありません。するべきではありません。

言われているトリガーに応じて異なるファイルを必要とするmain.jsを持っています

それは良い考えだとは思いません。必要になるすべてのrequireステートメントは、ファイルの先頭になければなりません。

また、_main.js_の_total.js_および_total.js_の_main.js_が必要であることもわかります。 require()関数は、ファイルの_module.exports_をインポートし、指定した名前空間に割り当てます。この方法でコードをファイルに分割しないでください。それらがモジュールである場合にのみ、コードを個別のファイルに抽出します。そして、そうすれば、あなたはお互いに2つのファイルをインポートしないでしょう。

また、javascriptでは、ネームスペースに何かを割り当てると、プリミティブの場合はコピー(クローン)されることに注意してください。オブジェクトの場合、両方の名前空間は同じオブジェクトを参照します

_var num = 5; 
var prim = num;
prim++; // prim is 6, but num is still 5.

var num = {five:5};
var ob  = num;
ob.five = 6;
console.log(num.five) //also 6.
_
1
Ooo

動作するが推奨されない小さなハックは、process変数を使用することです。それにさまざまなプロパティを適用し、ブラウザベースのJSのwindowオブジェクトと本質的に同じように使用できます。この小さなハックは、変数への参照を提供します。変更して操作することができ、変更はrequiredであるすべてのファイルに引き継がれます。

ただし、process変数をオーバーライドすると予期しない影響が生じる可能性があり、別のプロセスが干渉すると情報が失われる可能性があるため、お勧めできません。


file1.js:

const s1 = require('./file2');
process.num = 2;
console.log("file1", process.num);
s1.changeNum();
console.log("file1", process.num);

file2.js:

module.exports.changeNum = () => {
    process.num = 3;
    console.log("file2", process.num);
};

出力

file1 2

file2 3

file1 3

0
Jacob Schneider

または、他のすべての回答に対して

getterssetters

var _variableThing = 1223

module.exports = {
  get variableThing(){
    return _variableThing
  },

  set variableThing(val){
    _variableThing = val
  }
}

ただし、直接インポートでは機能しません

0
Aditya Shankar