2016-04-11 13 views
1

これはおそらく愚かな間違いですが、私は問題を見ることができません。 Angularjsアプリで画像ギャラリー用のオブジェクトの配列を作成しようとしています。各写真オブジェクトにはthumbimgという属性があります。 forループは細かいオブジェクトを作成していると私はそれらをチェックするために、コンソールにそれぞれのログを記録しています:角度アプリのFORループの予期しない動作

{thumb: "/10000/0_t.jpg", img: "/10000/0_l.jpg"} 
{thumb: "/10000/1_t.jpg", img: "/10000/1_l.jpg"} 
{thumb: "/10000/2_t.jpg", img: "/10000/2_l.jpg"} 
... 

しかし、このコードを実行した後:最終console.logが私に与え

var images = []; 
var image = {}; 
for (var i = 0; i < property.images.length; i++) { 
    image.thumb = "/" + property.id + "/" + i + "_t.jpg"; 
    image.img = "/" + property.id + "/" + i + "_l.jpg"; 
    console.log(image); //this gives expected output 
    images.push(image); 
}; 
console.log(images); //this gives all entries as the same 

{thumb: "/10000/27_t.jpg", img: "/10000/27_l.jpg"} //X28 

各画像。 27の画像は28の画像があるという事実から来ますが、私はなぜそれらのすべてが同じ経路を持っているのか理解できません。

+0

閉鎖、それを見て... Mr.Polywhirl @ –

+0

私はそれは、クロージャとは何かを持っているかわかりません。 .. – sp00m

+0

@ Mr.Polywhirl、クロージャでも各繰り返しで同じオブジェクトを参照します。あなたが考えているのはまったく別の問題です。 – Thomas

答えて

5

あなたが各反復で新しいオブジェクトを作成する必要があります。

var image; 
for (var i = 0; i < property.images.length; i++) { 
    image = {}; 
    image.thumb = "/" + property.id + "/" + i + "_t.jpg"; 
    image.img = "/" + property.id + "/" + i + "_l.jpg"; 
    console.log(image); //this gives expected output 
    images.push(image); 
}; 

そうでない場合は、各反復は再利用されますと同じ元のオブジェクトという。 .push()にオブジェクトを渡してもコピーは作成されません。

+1

あなたは秒で私を打ち負かす:D – Dilip

+0

ああもちろん - 私はそれを知っていたはずです。ありがとう – tommyd456

+0

あなたの答えを受け入れることについて - なぜループ内の 'console.log'が"期待された "出力を表示するのか説明できますか? – tommyd456

0

私のためにうまく動作します。 はJavaScriptで可能な限りの範囲を制限してください。

第16章を参照してください。Introducing a New Scope via an IIFEスクロールJavaScript

注: IIFEは「直ちに呼び出される関数式」です。これについて

var property = { 
 
    id : 10000, 
 
    images: [{ id: 1 }, { id: 2 }, { id: 3 }] 
 
}; 
 

 
var images = []; 
 

 
for (var i = 0; i < property.images.length; i++) { 
 
    (function(){ 
 
    var image = {}; // This should be inside the loop. 
 
        // This way the scope does not leak. 
 
    image.thumb = "/" + property.id + "/" + i + "_t.jpg"; 
 
    image.img = "/" + property.id + "/" + i + "_l.jpg"; 
 
    
 
    images.push(image); 
 
    }()); 
 
}; 
 

 
document.body.innerHTML = '<pre>' + JSON.stringify(images, null, 4) + '</pre>';

+1

JavaScript ES5にはブロックスコープがありません。この例では、 'image'の最後の値はforループの後に残ります。 JavaScript ES6では、 'var'の' let'インスタントを使うことができます。 ( 'let'にはブロックスコープがあります)。 ES5では、forループの後に 'image'を削除するか、または無名関数を使用してクロージャスコープを作成することができます。しかし、それを単純に保つために、コード全体を関数にラップします。 –

+0

ここにスコープを追加する必要はありません。問題はそれより簡単です。 – Pointy

1

方法:

var path = "/" + property.id + "/"; 
var images = property.images.map((img,i)=>{ 
    return { 
     thumb: path + i + "_t.jpg", 
     img: path + i + "_l.jpg" 
    } 
}); 
console.log(images); 
関連する問題