2007年11月26日 23:45 [Edit]
javascript - お伺い - Object.prototype.clone()
JavaScriptでオブジェクトのディープコピーをどうやってやるのか、これといったものがないようなので作ってCodeReposにおいておきました。
なぜこういうのが必要かというと、
var a = [0,1,2,3]; alert(a); // 0,1,2,3 var a2 = a; a2[4] = 4; // a2を変えると... alert(a2); // 0,1,2,3,4 -- aも変わってしまう!
からです。参照でオブジェクトを実装しているものにはJavaScriptでなくてもこうなっていて、それでは不都合なときのため、たいていの言語ではDeep Copyを実装するクラスやモジュールが提供されていますが(例えばPerlではStorable::dclone()、RubyならMarshalのloadとdumpを使って)、JavaScriptにはこれといったものが見当たらないのです。
現バージョンのはこちら。
/*
* $Id: clone.js,v 0.1 2007/11/26 14:17:22 dankogai Exp dankogai $
*/
(function(){
// They are atomic already
var atomic = [ Boolean, Number, String, Date, RegExp ];
for (var i = 0, l = atomic.length; i < l; i++){
atomic[i].prototype.clone = function(){ return this; }
}
// now the moment of truth!
Object.prototype.clone = function(){
if (this.prototype && this.prototype.clone
&& this.prototype.clone !== Object.prototype.clone)
return this.clone();
var clone = new (this.constructor);
for (var p in this) {
clone[p] = typeof this[p] == 'object' ? this[p].clone() : this[p];
}
return clone;
}
// Array needs some special care
Array.prototype.clone = function(){
var clone = [];
for (var i = 0, l = this.length; i < l; i++) {
clone[i] = typeof this[i] == 'object' ? this[i].clone() : this[i];
}
return clone;
}
})();
で、以下が実例。
-
Source:
- stdout:
- stderr:
オブジェクトの文字列化のため、KawaさんのJKL.Dumperを使わせていただいております。
見てのとおり、一つ嫌な問題があって、prototypeに割り当てているにも関わらず、for (k in object)でclone自身が見えてしまうのです。これって何とかならないのかなあ....__proto__プロパティを使う方法だと新しすぎる?
Dan the JavaScripter
Posted by dankogai at 23:45│Comments(2)│TrackBack(3)
この記事へのトラックバックURL
この記事へのトラックバック
404 Blog Not Found:javascript - お伺い - Object.prototype.clone()」でJKL.dumperを使ってみて、FirefoxのObject.toString()の挙動との不一致が気になったので、FireFoxでなくても使えるObject.toString()を作ってみました。
自分で言うのもなんですが、これは禿しく使え...
javascript - Object.toSource() for non-FireFox!【404 Blog Not Found】at 2007年11月27日 02:13
世の中にはdeep cloneの需要がある 僕もある。某ライブラリで実装せにゃならない。スマートな方法は思いつかず。永遠ループでまわしつづけています。この前見つけたネタのエントリ。 404 Blog Not Found:javascript - お伺い - Object.prototype.clone() 最速インターフェー
[JavaScript]object=clone(object);【Thousand Years】at 2007年11月28日 22:28
JavaScriptでオブジェクトをclone(ディープコピー)する方法を紹介する。 例えば、WebアプリのUIを作っていて、特定のタグ要素群を纏めてディープコピーしたいことも多々あるだろう。しかし、JavaScriptの標準APIではそれが実現出来ないようなので、今回はdankogai氏が作成…
JavaScriptでオブジェクトをクローンする方法。【俺の砂箱】at 2011年06月30日 17:30
この記事へのコメント
最初のコード 最終行
s/a2/a
s/a2/a
Posted by at 2007年11月27日 01:38
a2を変更するとaも変更されるっていう例示なら、
s/alert(a2)/alert(a)/g
では?
意味はもちろん、分かるんですが。
s/alert(a2)/alert(a)/g
では?
意味はもちろん、分かるんですが。
Posted by tmiz at 2007年11月27日 01:41