2015-09-13 13 views
7

私はThe Principles of Object-Oriented Javascriptを使っていますが、Zakasがオブジェクト内ではなく配列内に名前付きキーを使用するのと混同しています。コメントを参照してください:JS配列の名前付きキーの使用

function EventTarget() {} 

EventTarget.prototype = { 

    constructor: EventTarget, 

    addListener: function(type, listener) { 

     if (!this.hasOwnProperty("_listeners")) { 
      // Why isn't this: `this._listeners = {};` 
      this._listeners = []; 
     } 

     if (typeof this._listeners[type] === "undefined") { 
      this._listeners[type] = []; 
     } 

     this._listeners[type].push(listener); 
    }, 

    // more stuff 
} 

var target = new EventTarget(); 
target.addListener("message", function(event) { 
    console.log("Message is " + event.data); 
}); 

彼のコードは、(あなたがオブジェクトリテラルの配列を置き換えた場合にそれがないとして)正常に動作しますが、私の理解では、名前でコンテンツにアクセスしたい場合は、オブジェクトを使用する必要があるということでした。 array article on w3schools

多くのプログラミング言語では、名前付きインデックスを持つ配列がサポートされています。
名前付きインデックスを持つ配列は、連想配列(またはハッシュ)と呼ばれます。
JavaScriptはではありません。は名前付きインデックスを持つ配列をサポートしていません。
JavaScriptでの配列は常にの番号のインデックスを使用します。

Zakasがこのような配列を使用した理由はありますか?あなたはそれを説明してもらえますか?あるいは、これは私がthe errataに提出しなければならないものですか?

+0

'type'があれば、このコードが正しい:同様にあなた自身の例では、接続されたすべてのイベント・データが削除されるだろう - 次の例では、JSONシリアライザはfoo.bazで非数値アレイのプロパティを無視する方法を示します整数です – hindmost

+0

このコードは、実際の配列ではなく、配列オブジェクトのプロパティを設定しているため、引き続き動作します。 'Object.getOwnPropertyNames(this._listeners)'と 'Object.keys(this._listeners)'を確認してください。 'this._listeners'は配列ではなくオブジェクトでなければなりません。 – usandfriends

+0

@hindmost: 'type' *が整数でなくても、コードは正しいです(それは機能的です)。そして、' 'クリック ''のような文字列である可能性は非常に高いようです')。 –

答えて

5

私が見ることができる唯一の理由は、混乱している人々です。 JavaScriptは本当に何かを強制するものではなく、すべてがオブジェクトなので、あなたが望むものは何でもできます。この男は、名前付きプロパティを格納するために配列を使用していますが、関数やその他のものを使用している可能性があります。

編集:はほとんどすべてが(誰かがJavaScriptで最も一般的なエラーの1つは、undefinedにプロパティを設定しようとすることができますように私には発生していたオブジェクトであるTypeError : undefined is not an objectある JavaScriptがため息、なぜです。あなたは私たちにこれをやって?

+1

"すべてがオブジェクトです "。すべてではない! – undefined

+1

未定義はオブジェクトではありません... 'typeof undefined === "undefined" ' – usandfriends

2

Zakasは、このような配列を使用することを正当な理由がありますか?

引用されたコードから

、私は1つを考えることはできません、ありません。彼が使用していませんf _listenersが配列を参照しているとします。率直に言って、タイプミスのように見えます。それは(JavaScriptの通常の配列はオブジェクトなので)動作するので、タイプミスはキャッチされませんでした。まあ、あなたがそれをキャッチするまで。 :-)

配列を追加しているコードがない限り、その配列に *を追加すると、そこに配列を使用する理由はありません(おそらく2つの理由があります)。

* "配列エントリ" =キーがの配列インデックスのプロパティ。では、「配列インデックス」とは何ですか? "ToString(ToUint32(P))がPに等しく、ToUint32(P)232−1と等しくない場合に限り、Stringプロパティ名Pは配列インデックスです。spec

2

アレイは単なる特殊なオブジェクトです。

a=[] 
a[7]=9 
a["abc"]=20 
a["xxx"]=30 
for (i in a) console.log("value",i,a[i]) 

出力;

value 7 9 
value abc 20 
value xxx 30 
0

私はそれはタイプミスだと言うに傾いているが、それが意図されていたオフのチャンスで、次は私が...(警告を考え出すことができる唯一の機能的なユースケースである:月意見を分ける)。オブザーバー/イベントパターンは、任意のオブジェクトに適用することができ、一般的な概念であり(アンダースコアで示される)「プライベート」_listenersプロパティがありそうな目標を約知る必要がないことを考えると

- その後、それが含んでいるデータがオブジェクト自体に余計なものであることは間違いありません。

つまり、ターゲットオブジェクトをシリアライズすると、この種のデータを送信することはおそらく望ましくありません。

var foo = { 
    bar: {}, 
    baz: [] 
}; 

foo.bar['p1'] = foo.baz['p1'] = 1; 
foo.bar['p2'] = foo.baz['p2'] = 2; 

console.log(JSON.stringify(foo)); // {"bar":{"p1":1,"p2":2},"baz":[]} 
関連する問題