33

配列は変装した単なるオブジェクトですか? なぜ/なぜしないのですか?彼らはどのように(そのような/そうではない)ですか?

私は常に、JS の配列とオブジェクトは本質的に同じであると考えてきました。主な理由は、それらへのアクセスが同一であるためです。

var obj = {'I': 'me'};
var arr = new Array();
arr['you'] = 'them';

console.log(obj.I);
console.log(arr.you);
console.log(obj['I']);
console.log(arr['you']);

私は誤解を招く/誤解している/間違っていますか? JS のリテラル、プリミティブ、および文字列/オブジェクト/配列などについて何を知る必要がありますか?

配列/オブジェクトは変装した単なる文字列ですか? なぜ/なぜしないのですか?彼らはどのように(そのような/そうではない)ですか?

4

7 に答える 7

47

配列はオブジェクトです。

ただし、通常のオブジェクトとは異なり、配列には特定の特別な機能があります。

  1. 配列のプロトタイプ チェーンには追加のオブジェクトがありますArray.prototype。このオブジェクトには、配列インスタンスで呼び出すことができる、いわゆる Array メソッドが含まれています。(メソッドのリストはこちら: http://es5.github.com/#x15.4.4 )

  2. 配列にはlengthプロパティがあります(これはライブであり、自動更新されます)(ここを読んでください:http://es5.github.com/#x15.4.5.2

  3. 配列には、新しいプロパティの定義に関する特別なアルゴリズムがあります (こちらを参照してください: http://es5.github.com/#x15.4.5.1 )。新しいプロパティを配列に設定し、そのプロパティの名前が整数に強制できる文字列 ( '1''2''3'など) である場合、特別なアルゴリズムが適用されます (仕様の p. 123 で定義されています)。

これら 3 つの点を除けば、配列は通常のオブジェクトと同じです。

仕様の配列について読む: http://es5.github.com/#x15.4

于 2011-02-19T02:38:21.197 に答える
12

オブジェクトは文字列キーから値への順序付けられていないマップであり、配列は値の順序付けられたリストです(整数キーを使用)。それが主な違いです。これらは複数の値で構成されているため、どちらも非プリミティブです。これは、JavaScriptでの参照渡しも意味します。

ただし、配列も一種のオブジェクトであるため、配列に追加のプロパティをアタッチしたり、プロトタイプにアクセスしたりすることができます。

改訂された例では、配列が実際にはオブジェクトであるという事実のみを利用しています。つまり、配列に任意のプロパティを設定できます。あなたはそれをすべきではありません。値の順序付きリストが必要ない場合は、プレーンオブジェクトを使用してください。

于 2011-02-19T02:14:47.673 に答える
6

文字列は、宣言方法に応じて、プリミティブまたはオブジェクトのいずれかになります。

var str = 'yes';

あなたに原始的なものを与えますが、

var str = new String('yes');

Stringオブジェクトが表示されます。


すべての配列は同じであり([]またはnew Array()で定義されているかどうかに関係なく)、タイプオブジェクトであり、「Array」オブジェクトのプロトタイプから継承されます。Javascriptには実際のクラスはなく、すべてがオブジェクトであり、Arrayと呼ばれるシステム定義のオブジェクトがあります。'prototype'(オブジェクト型)というプロパティがあり、プロトタイププロパティを持つオブジェクトでnewキーワードを使用すると、プロトタイプのコンテンツへの参照を含むインスタンスが作成され、変数に格納されます。したがって、Javascriptでこれまでに使用したすべての配列は、Arrayのプロトタイププロパティのオブジェクトとインスタンスです。

いずれにせよ、配列は実際にはオブジェクトですが、便利なプロパティと関数(長さ、スライス、プッシュなど)があるため、配列のように動作します。

別の注意点として、クラスはないと言いましたが、これを行うと、次のようになります。

console.log(Object.prototype.toString.call(your_object));

[objectObject]という形式の文字列が表示されます。しかし、便利なのは、配列で呼び出すと、[objectFunction]を提供する関数や他の多くのシステム定義型と同じ[objectArray]が得られることです。これは、通常のオブジェクトと配列を区別するのに役立ちます(typeof演算子は常に文字列'object'を返します)。

これを試して

var a = Array;

そしてfirebugに入り、aの内容、特に'prototype'プロパティを調べます。

編集:より正確になるように、言い回しを少し変更しました。実際、newキーワードを使用すると、プロトタイプオブジェクトを参照するインスタンスが作成されます。したがって、インスタンスの宣言後にプロトタイプに加えられた変更は、引き続きインスタンスに影響します。

編集:あなたの最新の改訂された質問への回答(配列/オブジェクトは実際には変装した文字列です):いいえ。私が説明したように、それらはオブジェクトです。文字列は、プリミティブ型、またはプロパティの1つとして同等のプリミティブを含むオブジェクト型(Stringオブジェクトのインスタンス)のいずれかです。

于 2011-02-19T02:20:07.547 に答える
5

配列は Javascript のプリミティブではなく、オブジェクトです。主な違いは、結果として、配列を関数に渡すときに、値ではなく参照によって渡されることです。

あ、はい!配列は、本格的な Array.prototype とすべてを備えた JavaScript のオブジェクトです (ただし、触れないでください...)

この混乱は、javascripts を使用するとオブジェクト属性に 2 つの方法でアクセスできるという事実から生じます。

myObj.attribute または myObj["attribute"]

実際、配列を配列にするものは、データを格納する方法とは何の関係もありません。どのオブジェクトも、配列を格納するために使用する構文を使用して値を格納できます。配列を配列にするのは、配列メソッド (例: shift) です。 () と sort()) は Array.prototype に対して定義されています。

于 2011-02-19T02:11:55.213 に答える
1

私が最も重要であると信じていることを簡潔にしようとしています。配列には、オブジェクトにはないメソッドがいくつかあります。含む:

  • 長さ
  • 押す
  • ポップ

として宣言されたオブジェクトはvar x = {foo:bar}、.length()メソッドにアクセスできません。これらは両方ともオブジェクトですが、上記のメソッドを使用した一種のスーパーセットとして配列を使用します。

説明の面では、これがクロックフォードの標準に近いとは思いませんが、簡潔にしようとしています。

簡単な結果が必要な場合は、Firebugまたはjavascript Consoleを開き、Array.prototypeとObject.prototypeを試して詳細を確認してください。

更新:この例では、配列を宣言してから次のことを行います。

foo['bar'] = 'unexpectedbehaviour';

予期しない結果が生成され、次のような単純なループでは使用できなくなります。

var foo=[0,1];
foo['bar'] = 2;

for(var i=0;i<foo.length;i++){
    console.log(foo[i]);
}

//outputs: 
//0
//1

配列はオブジェクトを受け入れるfoo['bar']=xfoo.bar=y、またはいいねすることができますが、上で強調表示されているようにループスルーできるとは限りません。

オブジェクトのプロパティを反復処理できないと言っているわけではありません。配列を操作するときは、その独自の機能を利用しているので、混乱しないように注意する必要があります。

于 2011-02-19T02:19:42.597 に答える
1

JavaScript にはいくつかの型があり、それ以外はすべてオブジェクトです。JavaScript の型は、ブール値、数値、および文字列です。「null」と「undefined」という 2 つの特別な値もあります。

というわけで、「JavaScript 配列はオブジェクトですか?」というクエストです。やや曖昧です。はい、JavaScript 配列は「オブジェクト」ですが、「オブジェクト」のインスタンスではありません。JavaScript 配列は「配列」のインスタンスです。ただし、すべてのオブジェクトは Object から継承されます。MDCで継承チェーンを表示できます。さらに、配列にはオブジェクトとは少し異なるプロパティがあります。配列には.lengthプロパティがあります。.slice()、、.join()などのメソッドもあります。

Douglas Crockford は、この言語の機能に関する優れた調査を提供しています。彼の調査では、あなたが求めている違いについて説明しています。さらに、質問 #4559207 でリテラルとコンストラクターの違いについて詳しく読むことができます。

于 2011-02-19T02:55:48.227 に答える
0

配列はオブジェクトですが、特殊な性質を持っています。オブジェクトはキー (Javascript 表記法) によってインデックス付けされた値のコレクションですが{'key': 'value'}、配列はキーが数値 (いくつかの関数とプロパティを持つ) であるオブジェクトです。ループを使用すると、それらの主な違いは明らかですfor each。オブジェクトはそのプロパティのすべての値を反復処理しますが、配列は代わりにキーを返します。違いを示す JSFiddle へのリンクを次に示します。配列を使用する最初のfor each、値ではなくインデックスを返すことに注意してください。対照的に、2 番目for eachはそれらのキーの実際の値を返します。

于 2011-02-19T02:40:54.680 に答える