あなたのモジュールは実際にはリテラルを使用して初期化されたです。いくつかの誤解に取り組むことから始めます。オブジェクトは情報を隠すことはありません.JavaScriptの場合と同じように、JavaScriptにはprivate
とpublic
のスコープはありません。さらに、オブジェクトのプロパティにアクセスする唯一の方法は、あなたがmethod1
という変数を取得し、それを実行しようとしているため、これが失敗したことを通じて
method1();
にそれらにアクセスすることです。これは存在しないため、エラーです。ただし、はとなりますが、MyModule.method1()
となります。これは、MyModule
が実際のオブジェクトであるためです。 Javaでは、これはObject MyModule = new Object()
を持つのと似ています。このように、MyModule.toString()
のようなメソッドを呼び出すことができます - 唯一の "慣習的でない"ことは、インスタンスに大文字の名前が付いていることです - JavaとJavaScriptの変数は通常小文字で始まりますが、それを義務付ける。
次に、このラインがあります:
variable1 = 5; //silently assigns a variable inside MyModule to 5 ?
ライン上のコメントに答えるために - いいえ、それはしていません。上記の行はwindow.variable1 = 5
と同じです。あなたが持っているものは「暗黙のグローバル」と呼ばれています。名前はかなり自己記述的ですが、window.foo = 42
は明示的にグローバルなfoo = 42
です。はwindow
オブジェクトに戻るため、です。ただし、var foo = 42
はではなく、グローバルです。varキーワードは、グローバルwindow
オブジェクトにアタッチまたは使用されません。 "use strict"ディレクティブを使用すると、暗黙のグローバルに遭遇したときにJavaScriptエンジンがエラーをスローします。
は今、脇これらの誤解で、私は単にごまかすます別のマイナーなものもあるが、それは実際には大きなことだ - MyModule.method1
など機能ではなく、方法があります。メソッドは、それが割り当てられているオブジェクトである暗黙の状態を保持するサブルーチンのオブジェクト指向の用語です。しかし、関数は、本質的にオブジェクトに「属していない」フリーフローティング実行可能コードです。この区別はむしろ学術的に見えるかもしれませんが、それは大きな影響を与えます。しかし、私はあなたにこれを信じるように依頼します、これはここでカバーするには広すぎるトピックです。
これは間違っています。どうすればいいですか右?まず、スコープ上で、残りの部分に必要なように:
JavaScriptには、グローバルと機能の2つのスコープがあります。ここではまさに、これが何を意味するのかである:
var foo = 42;
function bar(input) {
var foo = input;
return foo;
}
console.log(bar(5)); //5
console.log(foo); //42
我々はfoo
と呼ばれる、あまりにも変数を持つ - 1を機能ではないの内側。 1つを割り当てることは、他のものを変更しない - 異なるスコープにあるためです。それは、関数の内部で省略された場合は、その後、我々は
var foo = 42;
function bar(input) {
foo = input;
return foo;
}
console.log(bar(5)); //5
console.log(foo); //5
同じものにアクセスすることになるインナーfoo
は、機能範囲にあることが宣言されていないので、これがあるので、それがアクセス - それはvar
キーワードのおかげです外側(そして外側には - window.foo
プロパティなし)。
これで十分です。しかし、ここに隠された側面がありますが、それはすぐには明らかではありませんが、だけがの2つのスコープがあります。ここでは、一見したところ、実際に最初のものと同じものだif文の内側に新しいfoo
プロパティを宣言していても、私はそう
function bar(condition) {
var foo = 5;
if (condition) {
var foo = 42;
}
return foo;
}
console.log(bar(false)); //5
console.log(bar(true)); //42
を意味するものです。他の言語のブロックスコープは{ }
なので、そこに宣言された変数はそこにとどまります。 JavaScriptでは真実ではありません。見逃しやすいので、注意することが重要です。
今、あなたの問題に。 には、非常に良い説明があります。Todd Mottoも、私が信じるものは、初心者のための良い記事ですが、the Adequately Good postはさらに深くなっていますが、まだアクセス可能です。それらはすべてモジュールパターンをカバーしています。実際には、それらのリソースやウェブ上に多くのモジュールパターンが見つかります。他の言語のpublic
とprivate
に似たものがあります。私はそれを説明しようとしない、私は他の人が私よりもそれを上手くやったと思うので。しかし、私はモジュールが何であるかを簡単に説明します。ここでも、他のリソースでこれをよりよくカバーできます。
モジュールは、クロージャ詳細情報hereとhere(StackOverflowの中で最も疑問を投げかけた質問の1つ)というJavaScript機能を利用しています。私が言ったことを覚えている、JavaScriptには2つのスコープがある?クロージャは、単純に言えば、機能的なスコープを提供します。あなたは(/* function goes here */)()
に囲まれて、あなたのコードと機能を持っているこの簡単に解剖するには
(function() { /* your code goes here */ })()
:ここではそれがどのように見えるかです。事実上、これは機能を実行するので、のすべてが機能スコープに入れられます。しかし、これは非常に強力で、ここに例があります。
var closure = (function() {
var privateVar = "secret";
return {
publicVar: 42,
getPrivateVar() { return privateVar; }
}
})()
console.log(closure.publicVar); //42
console.log(closure.getPrivateVar()); //"secret"
//let's change this
closure.publicVar = 5;
closure.privateVar = "changed";
console.log(closure.publicVar); //5
console.log(closure.getPrivateVar()); //"secret"
私たちは(私のものに似ている)プライベートフィールドを持っています。ここでも、var privateVar
は機能スコープ内で「ボトルアップ」したままで、外部からはアクセスできません。ちなみに、これはModuleパターンの例です。 var closure
の代わりに、私はそれをmyModule
と呼ぶことができました。それはむしろ単純化されていますが、ここではより複雑になることはありません。異なるモジュールはすべて、非常に似たようなものになっています。異なる方法でデータを公開するだけです。しかし、コンセプトは似ています。「プライベート」フィールドは内部にあり、「パブリック」フィールドは他の場所からアクセスできます。
これは長いですが、うまくいけば、基本的なことを説明してください。
これは名前空間でもモジュールでもありません。これは普通のJSオブジェクトです。すべてのプロパティが表示されます。私はなぜあなたが 'method1'がエラーを投げると思うのか分かりません - 私はそうは思わない。あなたが提供したJSFiddleではありません。 'variable1 = 5'はオブジェクト内の変数ではなくグローバル変数を割り当てます。 – vlaz
ここに(少し)更新された[JSFiddle](https://jsfiddle.net/xs4y1k19/1/)があります。これは実際にその関数がアクセス可能であることを示しています。脇に置く方法として、適用されないOOの用語があります - JavaScriptには機能があります。 – vlaz
@Vld:はい、そうです、何らかの理由で 'method1'は自分のJSFiddleにエラーを投げません。しかし、プロダクションコードにエラーが出るので、なぜそれを見つけるのにもっと時間を費やす必要があると思います。混乱の一部は、「存在しない変数、未定義変数の使用など」のような 'variable1 = 5'行にエラーが発生するという私の期待でした。 – Neolisk