web-dev-qa-db-ja.com

JavaScriptでのカプセル化はどこまで行けばよいですか?

1つの関数でのみ使用したい変数があります。私は次のようにコードを書くことができます:

var theAnswerToLife = 42

var multiplyIt = function(x) {
  return ++theAnswerToLife * x
}

そのファイルには、その変数を使用しない他の関数がいくつかあります。したがって、その変数へのアクセスをmultiplyIt関数のみに制限するために、IIFEでラップすることができます。

var multiplyIt = (function() {
  var theAnswerToLife = 42

  return function(x) {
    return ++theAnswerToLife * x
  }
}())

これで、その変数は内部関数でのみ使用できます。このようなカプセル化は、変数が多い場合は明らかに意味がありますが、変数が1つしかない場合は価値がありますか? IIFE構文は非常に重く、より複雑なコードでは、3つのネストされたIIFEのようになる可能性があります。

カプセル化とコードの可読性のバランスを保つ方法は?境界線はどこですか?


私の環境はNode.jsであるため、関数の外部で定義された変数はグローバルではなく、モジュールスコープでのみ使用できます。

単一の関数呼び出しを超えるスコープを持つ必要があるが、1つの関数だけでアクセスできる必要がある変数を考えると、その1つの関数だけに新しいスコープを導入しないことは問題ないと思います変数をグローバルにしないでください。

言い換えれば、この変数をモジュールスコープに配置します。明示的にエクスポートされない限り、トップレベルの変数が他のモジュールからアクセスされないようにする、ある種のモジュールシステムがすでにあるはずです。これは、従来のIIFEモジュールパターン、common.jsモジュール、またはその他の形式を意味する場合がありますが、それが何であれ、モジュールごとに新しい非グローバルスコープを導入する必要があるため、追加のIIFEがやり過ぎだと感じる場合はそのスコープを使用してください。

3
Ixrec

変数のスコープを制限することが目標である場合、問題を必要以上に難しくしています。

内部変数と関数の複雑さの両方について、はるかに限定されたスコープで同じ目標を達成するこの関数について考えてみます。

function doIt(x) {
  var theAnswer = 42;

  return x * 42;
}

それはあなたがするのと同じことをしますが、Clojureや IIFE(Immediately Invoked Function Execution) の追加の複雑さはありません。また、theAnswerをグローバル変数プールに公開しません。

このコードで呼び出すと、最後の行でエラーが発生します。

var results = document.getElementById("results");
results.innerText = "Function(3): " + doIt(3); 
results.innerText += ", theAnswer: " + theAnswer;
0
Adam Zuckerman