ここで注意すべき重要な点は、Javascriptは動的言語であるため、すべてのオブジェクトは、基本的に、単なる栄光のハッシュマップであるということです(いくつかの例外を除きます)。また、Javascriptオブジェクトのすべてには、角かっこ表記とドット表記の2つの方法でアクセスできます。
質問の最初の部分に答える2つの表記法について簡単に説明し、次に2番目の部分に進みます。
角かっこ表記
このモードは、他のプログラミング言語でハッシュマップや配列にアクセスするのに似ています。この構文を使用して、任意のコンポーネント(データ(他のオブジェクトを含む)または関数)にアクセスできます。
これはまさにあなたがあなたの例でしていることです。があります'a'
。これは文字列です(C ++などの言語のように文字リテラルではありません)。
角かっこ表記を使用して、そのtoUpperCase
メソッドにアクセスします。しかし、それにアクセスするだけではまだ十分ではありません。alert
たとえば、Javascriptで入力するだけでは、メソッドは呼び出されません。それは単純なステートメントです。関数を呼び出すには、括弧を追加する必要があります。パラメータを受け取らなかったため、をalert()
含む単純なダイアログボックスが表示されます。undefined
これで、この知識を使用してコードを解読できます。これは次のようになります。
alert('a'.toUpperCase());
これははるかに読みやすいです。
実際、これをもう少しよく理解するための良い方法は、次のJavascriptを実行することです。
alert(alert)
これは、2番目のアラートも実行せずにalert
、関数オブジェクトを渡すことによっても呼び出します。alert
表示されるのは(少なくともChrome 26では)次のとおりです。
function alert() { [native code] }
呼び出し:
alert(alert())
を含む2つの連続したメッセージボックスを示していますundefined
。これは簡単に説明できます。内部alert()
が最初に実行され、表示されundefined
(パラメーターがなかったため)、何も返されません。外部アラートは内部アラートの戻り値を受け取ります。これは何もありません。またundefined
、メッセージボックスにも表示されます。
jsFiddleですべてのケースを試してみてください!
ドット表記
.
これはより標準的なアプローチであり、ドット( )演算子を使用してオブジェクトのメンバーにアクセスできます。これは、ドット表記でのコードの外観です。
alert('a'.toUpperCase())
はるかに読みやすい。では、いつドット表記を使用する必要があり、いつブラケット表記を使用する必要があるのでしょうか。
比較
2つの方法の主な違いは、セマンティックです。他にもいくつかの詳細がありますが、それらについてはすぐに説明します。最も重要なのは、実際にやりたいことです。経験則では、オブジェクトが持つ確立されたフィールドとメソッドにはドット表記を使用し、実際にオブジェクトをハッシュマップとして使用する場合はブラケット表記を使用します。 。
このルールが非常に重要である理由の良い例をあなたの例で示すことができます-コードはドット表記がはるかに賢明だった場所でブラケット表記を使用しているため、コードが読みにくくなります。そして、それは悪いことです。なぜなら、コードは書かれているよりも何度も読み取られるからです。
場合によっては、ドット表記を使用する方が賢明であったとしても、角かっこ表記を使用する必要があります。
例:
for(var i = 0; i < 10; ++i) {
foo["method" + i]();
}
つまり、オブジェクトをハッシュマップとして使用する場合は角かっこ構文を使用し(foods["burger"].eat()
)、「実際の」フィールドとメソッドを操作する場合はドット構文を使用する必要があります(enemy.kill()
)。Javascriptは動的言語であるため、オブジェクトの「実際の」フィールドとメソッド、およびその中に格納されている「その他の」データの間の境界線はかなりぼやけることがあります。しかし、紛らわしい方法でそれらを混ぜない限り、あなたは大丈夫なはずです。
さて、あなたの質問の残りの部分に移りましょう(最後に!:P)。
メソッドが常にobjのメンバーになることをどのように確認できますか
できません。それを試してみてください。derp
文字列を呼び出してみてください。次の行でエラーが発生します。
Uncaught TypeError: Object a has no method 'derp'
任意のオブジェクトに対して任意のメソッドを呼び出すのは、ちょっと一般的な関数です。しかし、それは、指定されたメソッドがすでに指定されたオブジェクトの暗黙のメンバーになることを意味しますか?
はい、あなたの場合はそうしなければなりません。そうしないと、上記のエラーが発生します。ただし、関数で使用する必要はありません。独自の機能を追加して、map関数で使用することができます。すべての文字を大文字に変換するハードコードされたメソッドは次のとおりです。return obj[method]();
callMethod()
function makeCap()
{
return function(obj) {
return obj.toUpperCase();
}
}
var caps2 = map(['a', 'b', 'c'], makeCap()); // ['A','B','C']
console.log(caps2)
リンクしたチュートリアルのコードは、部分関数を使用しています。それらはそれ自体がトリッキーな概念です。その主題についてもっと読むことは、私がこれまでに作ることができたよりも物事をより明確にするのに役立つはずです。
注:これは、質問のコードで使用されているマップ関数のコードです。ソースはこちらです。
function map(arr, iterator) {
var narr = [];
for (var i = 0; i < arr.length; i++) narr.push(iterator(arr[i], i));
return narr;
}