3

私は次のJavaScriptコードを持っています。newキーワードを使用して配列を初期化したため、配列オブジェクトの新しいインスタンスを作成しました。次に、要素を追加して配列にデータを入力します。

しかし、私は根本的な誤解をしたと思います-それは私を大いに混乱させたコードの次の部分です、それが十分に明確でないか、それが単に間違っている場合は私の用語を修正してください。ログに記録しまし (beatles.length)た。長さプロパティを使用して、配列に含まれる要素の数を調べています。しかし、なぜその長さはプロパティであり、メソッドではないのですか?

長さは、実際には、配列オブジェクトが呼び出して数値を返すメソッドであるというわけではありませんか?長さがメソッドではない場合、なぜそれがプロパティ(配列オブジェクトに属する変数)なのですか?ここでその違いを簡潔に説明してください。

var beatles = new Array();
beatles[0] = "John";
beatles[1] = "Paul";
beatles[2] = "George";
beatles[3] = "Ringo";

console.log(beatles.length);
4

7 に答える 7

3

これ、要素を配列オブジェクトにプッシュするときに増減するプロパティです。

たとえば、私の(偽の)オブジェクト:

var myArray = function(){
   this.length = 0;

   this.push = function(itm){
       this.length++; 
       // ^ doesn't do anything aside from increase length
   };
};
于 2013-01-22T17:31:10.817 に答える
2

Stringとは両方ともArraysObjectsであり、基本的な変数型ではありません。

したがって、lengthはジェネリックオブジェクトのメンバー変数であり、Object配列と文字列の両方で一般的に使用できます。Stringの場合は文字列の長さを返し、Arrayの場合はオーバーライドしてカウントを返します。

小さな例は次のとおりです。

var a = "Hello";
var b = new Array();
b[0] = "Hello";
b[1] = "World";
a.length    // returns 5
b.length    // returns 2
于 2013-01-22T17:31:24.953 に答える
2

関数は毎回再計算する必要がないため、関数である必要は.lengthありませんが、要素をオブジェクトにプッシュするときに必要に応じて増減し[]ます。

関数はべき等である可能性がありますが、プロパティは常にべき等である.lengthため、より適切に適合します。

関数は通常、状態を変更する.pushか(のように)、受け取った引数に基づいて異なる値を返します(.slice.splice)。

別のメモで:

配列を初期化するための推奨される方法はvar a = [];、であり、要素を追加するには、を使用する必要がありますa.push(element);

于 2013-01-22T17:31:36.093 に答える
2

Array.lengthプロパティは、実際には2つの(非表示の)メソッドget()と、set()アクセサーとも呼ばれるのカプセル化です。

式でプロパティを使用すると、 JavaScriptが内部的に呼び出しget()ます。例:

var n = fields.length;

逆にset()、割り当てで使用される場合は呼び出します。例:

fields.length = 1;

これにより、配列アイテムも更新され、次の条件を満たすようになります。

プロパティの値は、length常に最大アイテムインデックスより1つ高くなります(存在しない場合はゼロ)。

これは重要な詳細です。これは、場合によっては、配列内の(null以外の)アイテムの数と厳密に同じではないためです。

于 2013-01-25T08:56:11.180 に答える
1

length疑似プロパティであり、それを機能させるために内部で何かが起こっています。

lengthゲッターとセッターのように動作します(関数のように)。プロパティのようにアクセスしますが、プロパティのように削除することはできません:(delete beatles.length失敗します)。

配列に要素を追加すると、lengthそれに応じてプロパティが変更されます。

lengthプロパティを設定beatles.length = 0;すると、配列が変更されます-配列がクリアされます。

現在、同様の機能を自分で作成する方法はありません(明示的なget / setterを使用する以外)。この一部は、新しいES5(または6?)標準で利用できるようになります。不変のプロパティを作成する機能のように。インデックス付きの割り当ての魔法は配列に固有のものですが、それは言語機能です。

言語設計者が関数ではなくプロパティを作成した理由については、おそらくパフォーマンス、おそらく他の言語(もちろんJava)との類似性です。

ソース:

https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/get https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Operators/set

于 2013-01-22T17:34:21.810 に答える
1

この場合、lengthはjavascriptエンジン自体によって常に有効に保たれるプロパティです。

于 2013-01-22T17:31:31.617 に答える
0

これはプロパティですが、言語全体の他のプロパティとは異なります

配列は、あなたが精通しているものとまったく同じ種類のオブジェクトではありません(ただし、配列は非常に接近しています)。仕様では、プロパティを正常に機能させるために、配列エキゾチックオブジェクトlengthと呼ばれる特別なタイプのオブジェクトを定義しています。すべての配列は、実際には標準オブジェクトではなく、この種のエキゾチックオブジェクトです。他にもいくつかの種類のエキゾチックなオブジェクトがありますが、ここで関係するのは配列用のオブジェクトです。

プロパティの基本はlength十分に単純に見えます。それは配列内の要素の数です。しかし、これを最新の状態に保つには、かなりの量の舞台裏の魔法が必要です。ゲッターやセッターでさえ、それを完全に処理することはできません。

その理由は、Arrayプロパティの実際の定義にありlengthます。オブジェクトのプロパティ名を見ると、それらの一部を数値で表すことができる場合があります。これが可能な場合は、数値の1つがより大きい必要があります。他のすべて。配列のエキゾチックオブジェクトには常にと呼ばれるプロパティがlengthあり、そのプロパティの値は常にそのオブジェクトのそのような最大数よりも大きくなければなりません。他のプロパティが変更された場合、他のプロパティの名前によっては、配列も変更する必要がある場合があります。lengthしたがって、すべてのプロパティの変更を監視して、予定されているときに更新されることを確認する必要があります

現在、JavaScriptでそれを行う方法はありませんセッターを使用して、特定のプロパティへの変更を監視する関数を使用することはできますが、オブジェクトのすべてのプロパティの変更を監視する一般的な関数を使用することはできません。ECMAScript 6は、プロキシオブジェクトを介してこれを行う方法があるように見えますが、まだ完全にサポートしているブラウザはありません。

于 2014-11-06T18:06:43.780 に答える