2017-01-06 10 views
1

配列に新しいageキー:値のペアが含まれている理由がわかりません。
私はそれをスライスして(したがって、独立したコピーを作成することによって)私はnewArrayで単独で働くことができ、それにageを追加することができました...しかし、personsも更新しているようですね??事前に
おかげJavascript:sliceの後に重複した配列が正しくなく、keyValueが追加されています

const persons = [ 
 
    { first: 'Albert', last: 'Einstein', birthYear: 1879, deathYear: 1955 }, 
 
    { first: 'Isaac', last: 'Newton', birthYear: 1643, deathYear: 1727 }, 
 
    { first: 'Galileo', last: 'Galilei', birthYear: 1564, deathYear: 1642 }, 
 
    ]; 
 

 
function appendAge(originalArray) { 
 
    var newArray = originalArray.slice(0); 
 

 
    newArray.forEach(item => { 
 
    item['age'] = item.deathYear - item.birthYear; 
 
    }) 
 
    return newArray 
 
} 
 
console.info(persons) 
 
var newPersons = appendAge(persons) 
 
console.info(newPersons)

答えて

3

sliceはコピーのみ参照を含む値の最上位レベルを、それを意味する、シャローコピーを行い、そして実際に参照値そのものをコピーしません。

これは、両方の配列の各Personオブジェクトが同じオブジェクトであることを意味します。

あなたの人物オブジェクトのカスタムコピー機能を作成し、それをmapと一緒に使用して配列をコピーするのが簡単な解決策です。

const people = [ 
 
    { first: 'Albert', last: 'Einstein', birthYear: 1879, deathYear: 1955 }, 
 
    { first: 'Isaac', last: 'Newton', birthYear: 1643, deathYear: 1727 }, 
 
    { first: 'Galileo', last: 'Galilei', birthYear: 1564, deathYear: 1642 }, 
 
    ]; 
 

 
function copyPerson(person) { 
 
    return Object.assign({}, person); 
 
} 
 

 
function copyPeople(people) { 
 
    return people.map(copyPerson); 
 
} 
 

 
function appendAge(people) { 
 
    const newArray = copyPeople(people); 
 

 
    newArray.forEach(item => { 
 
    item['age'] = item.deathYear - item.birthYear; 
 
    }); 
 

 
    return newArray; 
 
} 
 

 
console.info('----------------------------------------'); 
 
console.info('Old People'); 
 
console.log(people) 
 
console.info('----------------------------------------'); 
 
console.info('New People'); 
 
console.log(appendAge(people));

また、他のソリューションのためのHow do I correctly clone an object in JavaScriptをチェックアウトすることができます。

+0

'.map()'は新しい配列を作成するので、 '.map()'も呼び出す場合は '.slice()'を使う必要はありません。 – Barmar

+0

@Barmarあなたは正しい、私の悪い、固定された今 – nem035

+0

素晴らしい...超高速返信のおかげで...私は浅い対深いコピーについて少しは読んでいたが、実際にそれを把握していなかった。このソリューションは完璧です。 – sigmazen

3

personsアレイのコピーを作成しました。オリジナルのオブジェクトへの参照を含み、それらのオブジェクトのコピーは含まれません。完全なコピーを作成するには、オブジェクトも複製する必要があります。

Object#assignはオブジェクトのトップレベルプロパティのみをコピーするので、オブジェクトはdeep cloneにする必要があります。

const persons = [ 
 
    { first: 'Albert', last: 'Einstein', birthYear: 1879, deathYear: 1955 }, 
 
    { first: 'Isaac', last: 'Newton', birthYear: 1643, deathYear: 1727 }, 
 
    { first: 'Galileo', last: 'Galilei', birthYear: 1564, deathYear: 1642 }, 
 
    ]; 
 

 
function appendAge(originalArray) { 
 
    return originalArray.map((item) => Object.assign({}, item, { 
 
    age: item.deathYear - item.birthYear 
 
    })); 
 
} 
 

 
var newPersons = appendAge(persons); 
 
console.info(newPersons); 
 
console.info(persons); // persons haven't changed

+0

なぜ 'Object.assign'、なぜ単純に' originalArray.map(item =>(age:item.deathYear - item.birthYear))) ' – DavidDomain

+1

@DavidDomain OPは、コピーされた各人の新しいプロパティとして「年齢」を追加したいが、人物オブジェクト全体を上書きしないためです。 – nem035

+0

ああ、申し訳ありませんが、新しい配列には年齢だけが必要だと思っていました。 – DavidDomain

1

あなた.forEachループは配列ではなく、スライスを更新しているもの、実際にあります。スライスはコピーを作成していますが、渡すとforEachループに入ります。だからあなたがコピーと思っているものにあなたのアイテムを追加しているとき、オリジナルに追加しています。

+0

私はこれがあなたの質問に答えたと思います。コピーを更新する理由は分かりません。多分あなたは比較をしているのでしょうか?もしそうなら、オリジナルの深いクローンを作成し、initで変数に格納してから、save/updateでオリジナルを更新したものに...ちょうどここで推測する –

関連する問題