web-dev-qa-db-ja.com

コロン付きのJavaScriptリターン

私はJavaScriptを学習していて、以下の構造に遭遇しました:

var Test = (function () {

  function func1() {
      //do something.....
  }

  function func2() {
      //do something.....
  }

  function func3() {
      //do something.....
  }

  return {
      func1: func1,
      func2: func2,
      func3: func3
  };

})();

戻りブロックが何をしているのかと思います。これは非常に一般的に使用されているJavaScript構造ですか?これに関する詳細情報はどこで入手できますか。

54
Sean

これはRevealing Module Patternです。

返されるオブジェクトには、IIFE内で定義された関数への参照が含まれています。したがって、内部で定義されている関数は、匿名関数に対してprivateです。

ただし、外部の内部関数を使用する場合は、返されたオブジェクトを使用できます。

Testの値は

_var Test = {
    func1: func1,
    func2: func2,
    func3: func3
};
_

そして、あなたは_func1_を外部から呼び出すことができます

_Test.func1();
_

これはJavascriptemulateclassの方法です。モジュールパターンを使用する可視性指定子がないため、変数/メソッドをパブリック/プライベートにすることができます。

enter image description here

明らかにするモジュールパターンは、モジュールパターンからインスピレーションを得ています。モジュールパターンの表示では、private変数/メソッドへの参照のみがobjectで返されます。

パターンの背後にある主なアイデアは、邪悪なグローバル変数を回避することです。これは、関数の代わりにオブジェクトが返されることを除いて、IIFEに似ています。 IIFE内で定義された変数/メソッドは、関数に対してprivateです。 IIFE内の変数/メソッドにアクセスするには、返されたオブジェクトに追加する必要があり、IIFEの外部からアクセスできます。このパターンはclosuresを利用するため、オブジェクトが返された後でも、IIFE内で定義された変数/メソッドにアクセスできます。

Addy Osmaniの本から Javascriptのデザインパターンを学ぶ

ある公開メソッドを別のメソッドから呼び出したり、パブリック変数にアクセスしたりするときにメインオブジェクトの名前を繰り返す必要があるという事実にハイルマンが苛立っていたため、Reveilinging Moduleパターンが発生しました。また、公開したいものをオブジェクトリテラル表記に切り替える必要があるというモジュールパターンの要件も嫌いでした。

彼の努力の結果は、更新されたパターンであり、プライベートスコープですべての関数と変数を定義し、パブリックとして公開したいプライベート機能へのポインターを含む匿名オブジェクトを返します。

利点:

  1. カプセル化。 IIFE内のコードは外部からカプセル化されています
  2. クリーンで整理された再利用可能なコード
  3. プライバシー。プライベート変数/メソッドを作成することができます。プライベート変数/メソッドは、IIFEの外部からは操作できません。

欠点:

  1. プライベート関数がパブリック関数を参照する場合、そのパブリック関数はオーバーライドできません

参考文献:

  1. https://en.wikipedia.org/wiki/Module_pattern
  2. https://carldanley.com/js-revealing-module-pattern/
  3. JavaScriptでモジュールパターンを表示する方法

[〜#〜]編集[〜#〜]

From comment from @ Mike

オブジェクト(たとえば、_var me = {};_)を作成し、その上でパブリックメンバーになることを宣言する(me.func1 = function() { /* ... */ };)ことは一般的であり、そのオブジェクトを最後に返します(_return me;_)。これにより、OPのコードのreturnステートメント(すべてのパブリックなものが繰り返される)で見られるような繰り返しが回避されます。

71
Tushar

これは、returnステートメントのリテラルオブジェクトです。オブジェクトを作成して返すようなものです。

var obj = {
    func1: func1,
    func2: func2,
    func3: func3
};
return obj;

リテラルオブジェクト構文は、次のようにオブジェクトを作成し、そのプロパティを設定します。

var obj = new Object();
obj.func1 = func1;
obj.func2 = func2;
obj.func3 = func3;
return obj;

オブジェクトを返す目的は、関数が使用できるプライベート変数のスコープを作成しながら、関数内の関数を外部のコードに明らかにすることです。

プライベート変数を使用しない場合、コードは次のものと同じことを行います。

var Test = {
  func1: function() {
      //do something.....
  },
  func2: function() {
      //do something.....
  },
  func3: function() {
      //do something.....
  }
};

プライベート変数は関数スコープ内で宣言され、その内部の関数によってのみ到達可能です。例:

var Test = (function () {

  var name;

  function setName(str) {
    name = str;
  }

  function getName() {
    return name;
  }

  return {
      setName: setName,
      getName: getName
  };

})();

Test.setName("John Doe");
var name = Test.getName();
15
Guffa

これは、他のプログラミング言語のクラスのように機能します。したがって、_func1_を使用してパブリック_Test.func1_メンバーにアクセスし、Test.func1()を使用して通常の関数のように呼び出すことができます。

1
Iulian Onofrei