オブジェクト、配列のコピー

JavaScript では、オブジェクトや配列を関数に渡す時、常にポインタが使われます。いわゆる copy by reference ですね。変数に代入する場合も同様です。

当然メモリー効率を配慮した設計な訳ですが、どうしてもコピーが欲しい時もあるものです。

配列のコピーを取りたい時はどうすればいいでしょうか。

var a = [1, 2, 3];
var b = []; b.unshift(a);

うまくいった気がしませんか? 実はこれは駄目なんですね。unshift が引数に取るのは、配列ではなく、配列に加えたい要素のリストなので、ここでは b[0] に a が丸ごと入ってしまっていることになります(私はこれに気付かず長時間悩みました)。

で、改めて調べたところ、concat メソッドを使えば良いことがわかりました。

var a = [1, 2, 3];
var b = a.concat();

これで、同じ内容をもつ別の配列オブジェクトになります。

記法が一緒なのであまり意味はないですが、clone メソッドとして定義しておいても良いでしょう:

Array.prototype.clone = function ()
{
    return this.concat();
};

オブジェクトの場合はどうでしょうか。レファレンスを見ても、配列のような便利なメソッドは見当たらないので、prototype.js の extend の様に、メンバーを一つ一つコピーしていく方法しか無さそうです。ということで、clone メソッド:

Object.clone = function (object)
{
    return Object.extend({}, object);
};

id:reinyannyan:20051015:1129388215 で紹介しましたように、prototype に追加することは避けるべきでしょう。