11

いくつかのオブジェクトを含む JavaScript 配列で奇妙な動作が発生しています (まったく奇妙ではないかもしれませんが、その理由を理解していないだけです)。

私はJavaScriptのプロではないので、なぜこれが起こっているのかについて明確な説明があるかもしれませんが、私にはわかりません。

ドキュメントで実行されている JavaScript があります。次のようなオブジェクトの配列を作成します。

var myArray = [{"Id":"guid1","Name":"name1"},{"Id":"guid2","Name":"name2"},...];

この配列を JSON.stringify(myArray) のように作成した場所に出力すると、期待どおりの結果が得られます。

[{"Id":"guid1","Name":"name1"},{"Id":"guid2","Name":"name2"},...]

ただし、子ドキュメントからこのドキュメント (最初のドキュメントによって開かれたウィンドウ内のドキュメント) にこの配列にアクセスしようとすると、配列は配列ではなくなります。したがって、子ドキュメントで JSON.stringify(parent.opener.myArray) を実行すると、次のようになります。

{"0":{"Id":"guid1","Name":"name1"},"1":{"Id":"guid2","Name":"name2"},...}

そして、これは私が期待していたものではありませんでした - 親ドキュメントで行ったのと同じ結果になると期待していました。

なぜこれが起こっているのか、子ウィンドウ/ドキュメントからアドレス指定されたときに配列が配列のままになるように修正する方法を誰かに説明できますか?

PS。オブジェクトは上記のように配列に追加されません。次のように追加されます。

function objTemp()
{
    this.Id = '';
    this.Name = '';
};

var myArray = [];

var obj = new ObjTemp();
obj.Id = 'guid1';
obj.Name = 'name1';

myArray[myArray.length] = obj;

それが違いを生むなら。

私の問題を解決するためだけでなく、何が起こっているのかをよりよく理解するためにも、どんな助けも大歓迎です:)

4

2 に答える 2

7

一番最後の行が問題を引き起こしている可能性がありmyArray[myArray.length] = obj;ますmyArray.push(obj);。新しいインデックスを明示的に作成しているため、配列がオブジェクトに変換されている可能性があります...ただし、ここでは推測しています。を取得する子ドキュメントで使用されるコードを追加していただけますmyArrayか?

編集

違いはありませんので、上記を無視してください。とはいえ、自慢するつもりはありませんが、私は正しい方向に沿って考えていました. 私の考えは、独自の配列メソッドのみを使用することで、インタープリターはそれをmyArray. 親ドキュメントに関する限り、配列ですが、あるドキュメントから別のドキュメントに配列を渡すため、次のようになりますmyArray

配列は、独自のプロトタイプとメソッドを備えたオブジェクトです。それを別のドキュメントに渡すことで、Array オブジェクト全体 (値とプロトタイプ) を 1 つのオブジェクトとして子ドキュメントに渡します。ドキュメント間で変数を渡すことで、効果的に変数のコピーを作成しています (JavaScript が var の値をコピーするのはこのときだけです)。配列はオブジェクトであるため、そのすべてのプロパティ (およびプロトタイプ メソッド/プロパティ) は、Objectオブジェクトの「名前のない」インスタンスにコピーされます。の行に沿って何かvar copy = new Object(toCopy.constructor(toCopy.valueOf()));が起こっています...これを回避する最も簡単な方法、IMOは、親コンテキストで配列を厳密にすることです。なぜなら、インタープリターはそれが配列であることを知っているからです:

//parent document
function getTheArray(){ return JSON.stringify(myArray);}
//child document:
myArray = JSON.parse(parent.getTheArray());

この例では、var は、依然としてmyArray真の JavaScript 配列として扱われるコンテキストで文字列化されているため、結果の文字列は期待どおりになります。JSON でエンコードされた文字列をあるドキュメントから別のドキュメントに渡す場合、文字列は変更されないため、変数JSON.parse()の正確なコピーが得られます。myArray

これは暗闇の中での別の野生の突き刺しに過ぎないことに注意してください。しかし、もう少し考えてみました。これについて間違っている場合は、お気軽に訂正してください... 私はいつでも喜んで学びます。これが本当であることが判明した場合は、遅かれ早かれ間違いなく私にとって落とし穴になるので、私にも知らせてください

于 2012-05-02T09:17:42.003 に答える
1

この動作と説明の例については、この記事の最後http://www.karmagination.com/blog/2009/07/29/javascript-kung-fu-object-array-and-literals/を参照してください。

基本的には、配列がネイティブ型であり、各フレームが独自のネイティブと変数のセットを持つことになります。

記事から:

// in parent window
var a = [];
var b = {};
//inside the iframe
console.log(parent.window.a); // returns array
console.log(parent.window.b); // returns object

alert(parent.window.a instanceof Array); // false
alert(parent.window.b instanceof Object); // false
alert(parent.window.a.constructor === Array); // false
alert(parent.window.b.constructor === Object); // false

JSON.stringify への呼び出しは、実際には次のチェック (json.js ソースから) を実行します。これは、配列としての指定に失敗しているようです。

        // Is the value an array?
        if (Object.prototype.toString.apply(value) === '[object Array]') {
           //stringify
于 2012-05-02T09:24:07.897 に答える