2016-03-10 1 views
9

私はmap()の動作がかなり混乱しています。なぜアレイ上のjsマップが元の配列を変更するのですか?

私はこのようなオブジェクトの配列があります

const products = [{ 
    ..., 
    'productType' = 'premium', 
    ... 
}, ...] 

を、私は同じ配列を返すべき関数ではなく、すべての製品で、この配列を渡しているがなさフリー:

[{ 
    ..., 
    'productType' = 'free', 
    ... 
}, ...] 

関数は次のとおりです。

const freeProduct = function(products){ 
    return products.map(x => x.productType = "free") 
} 

次の配列を返します。

["free", "free", ...] 

だから私はあることを私の機能を書き直し:意図したとおりの配列を返します

const freeProduct = function(products){ 
    return products.map(x => {x.productType = "free"; return x}) 
} 

を。

BUT!そして、それが私の心が失われた瞬間です。どちらの場合も、私の元の製品アレイは変更されています。

map()のドキュメントには、(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)は含まれていないと記載されています。

私も私の配列は、この

const freeProduct = function(products){ 
    p = products.splice() 
    return p.map(x => {x.productType = "free"; return x}) 
} 

ように私の機能を回すのクローンを作成しようとしましたが、私はまだ(狂気私を駆動するために開始します)同じ結果を得ます。

私が間違っていることを私に説明できる人には、とても感謝しています!

ありがとうございました

答えて

26

元の配列は変更していません。配列内のオブジェクトを変更しています。あなたは、配列内のオブジェクトを変異避けたい場合は、元のプロパティを持つ新しいオブジェクトに加え、必要な変更を作成するためにObject.assignを使用することができます。

const freeProduct = function(products) { 
    return products.map(x => { 
    return Object.assign({}, x, { 
     productType: "free" 
    }); 
    }); 
}; 
+0

こんにちは。上記のコードでは "=>"の意味は何ですか? –

+1

@ HarshaKanchinaこれはES6で追加された太い矢印の関数構文です。 [こちら](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions#Arrow_functions)は、MDNに関する情報です。 – SimpleJ

+0

Javascriptは機能的な言語になりがちですが、classキーワードのように、これは混乱しやすく、直感的ではなく、多くの時間を無駄にします。 '元の配列は変更していません。あなたは配列のオブジェクトを変更しています - この答えは正しいが、現実世界では何かの部分を変更したり、同じままにしたりすることができないので、非論理的です。 – Cobolt

8

SimpleJの答えについて詳しく説明するには - あなたは==した場合= 2つの配列は、マップされた配列が実際には新しい配列であることを確認しても、同じではない(メモリ内の同じアドレスではない)ことがわかります。問題は、新しい配列を返すことです。元の配列のSAMEオブジェクトへの参照がいっぱいです(新しいオブジェクトリテラルを返さず、同じオブジェクトへの参照を返しています)。したがって、古いオブジェクトのコピーである新しいオブジェクト、つまりSimpleJによって与えられたObject.assignの例を作成する必要があります。

関連する問題