lodashのclone(isDeep)とcloneDeepの検証
lodashには_.cloneと_.cloneDeepというオブジェクト複製のコマンドがあります。 cloneの方は基本的にShallowCloneととでも言うのか、参照の複製を行います。 一方cloneDeepは参照の複製ではなく、同じ値のオブジェクトを再生成して複製します。ここまでなら解りやすいですね。
ですがcloneにはisDeepというパラメータにtrueを渡すことでdeepにcloneできるというのです。
じゃぁclone(isDeep)とcloneDeepの違いはなんなんだ?ということで簡単に調べてみました。
var users = [ { 'user': 'john', 'age': 35 }, { 'user': 'fred', 'age': 29 } ]; var cloneShallow = _.clone(users); var cloneIsDeep = _.clone(users, true); var cloneDeep = _.cloneDeep(users); console.log(users[0] == cloneShallow[0]); // true console.log(users[0] == cloneIsDeep[0]); // false console.log(users[0] == cloneDeep[0]); // false
JavaScriptの等価演算子でオブジェクトを比較した場合、オブジェクトの参照先が同じかどうかで判断されます。 よって、通常のcloneの場合usersとcloneShallowは同じ参照を持っている為trueになりますね。 一方clone(isDeep)とcloneDeepは新しいオブジェクトを生成するのでfalseになります。
あれ?同じ?
ちなみに勿論ですが各objの値自体は同じです。
console.dir(users); console.dir(cloneShallow); console.dir(cloneDeeper); console.dir(cloneDeepest); // 上記の結果は全て以下の通り // [[object Object] { // age: 35, // user: "john" // }, [object Object] { // age: 29, // user: "fred" // }]
結局ソース見てみたんですが、同じでした。 cloneもcloneDeepもbaseCloneというprivateメソッドを利用していて、それに対してparamのisDeepを引数として渡すか固定で渡すかの違い。
baseClone(obj, isDeep); //clone baseClone(obj, true); //cloneDeep