2009-07-22 10 views
1

このトピックをもう一度読むのは本当に面倒です。コードを読み込む前に、JavaScriptでプロトタイプやオブジェクトを取得できない場合がありますが、この時点では。JavaScriptオブジェクトの複製。もう一度:(

問題がある:
延長し、その後の実行時にそのまま残っている「クローン」クラスのように、(プロトタイプを使用して作成)のJavaScriptクラスのクローンを作成する方法

function clone(obj){ 
    if(obj == null || typeof(obj) != 'object') 
     return obj; 

    var temp = new obj.constructor(); 
    for(var key in obj) 
     temp[key] = clone(obj[key]); 

    return temp; 
} 

var FOO = function() { 
    var myBAR = clone(BAR); 
    myBAR.prototype = jQuery.extend(true, myBAR.prototype, this); // deep cloning twice and extending with this 
    console.log("FOO:", this.name); 
    new myBAR(); 
}; 

FOO.prototype = { 
    name: "FOO" 
}; 

var BAR = function() { 
    console.log("BAR:", this.name); 
}; 

BAR.prototype = { 
    name: "BAR" 
}; 

new FOO(); // returns FOO: FOO and BAR: FOO 
new BAR(); // returns BAR: FOO should return BAR: BAR 

i」は場合は?それが正しいのですが、new BAR()new FOO()の後)の2番目の呼び出しは、 n BAR: BARではありません。現時点ではBAR: FOOです。この問題の

一つの可能​​な解決策は、このようなものでclone機能を完全に書き直したものです:

function clone(obj) { 
    return eval("("+obj.toString()+")"); // the same as eval(uneval(obj)); 
} 

しかし、このアプローチは、BIG欠点を持っている、あなたは、任意の動的に作成されたオブジェクトを渡すことはできません。

アイデア?

+1

「動的に作成されるオブジェクト」とはどういう意味ですか? –

+0

FOOの内部にCATのインスタンスを作成し、this.cat = new CAT();のようにCATをプロパティとして保存し、CATクラスがDOM要素への参照を作成して保存したとします。 this.myBody = $("body")のように。 –

+0

クローニングプロセスで、いつコピーしたいのですが、いつ参照をコピーしますか? – Rojo

答えて

0

私は上記の問題の解決策を誰かに見せたいと思っています。

function cloneClass (func) { 

    if(typeof func == 'function') { 

    var prototype = {}; 
    for (var prop in func.prototype) { 
     prototype[prop] = func.prototype[prop]; 
    }; 

    var Class = function() { 
     var _this = this; 
     var constructor = function() { 
     func.apply(_this, arguments); 
     }; 
     constructor.prototype = _this; 

     for (var property in func) { 
     if(property != "prototype") { 
      constructor[property] = func[property]; 
     } 
     }; 

     return constructor; 
    }; 

    Class.prototype = prototype; 
    return new Class(); 
    } 

    return func; 

}; 

これがどのように機能しているかを理解してください。誰もこの実装、メモリリークなどの問題を見ることができますか?

+0

誰にも感謝してくれました。 –

+0

私はChristophの解決策がjavascriptの 'クローニング'に対処する通常の方法だと思います。ダミー関数のプロトタイプを、複製するオブジェクトに設定し、 'new'で関数を呼び出します。そして、ビオラ、クローンがあります。 –

0

javascriptオブジェクトを複製する際の問題は、どれだけ深く進むことになりますか?

は、私は以下の目的を持って考えてみましょう:

var obj = { 
    prop : { 
     n1prop : { 
      hello : 'world'; 
     } 
    } 
}; 

これは、私はあなたが深いネストを持っている場合、非常に高価得ることができるタイプの「オブジェクト」であるすべてのプロパティを横断しなければならないことを意味します。

単純な1レベルのオブジェクトを使用している場合は、ループのための単純なリフレクションを使用して新しいオブジェクトリテラルを作成することができます。 注:元のオブジェクトのメソッドはコピーされません。

function clone(obj) { 
    var cloned; 

    if (obj && typeof obj === 'object') { 
     cloned = {}; 
     for (var p in obj) { 
      if (obj.hasOwnProperty(p) && typeof obj[p] !== 'function') { 
       cloned[p] = obj[p] 
      } 
     } 
     return cloned; 
    } 
    else { 
     return null; 
    } 
} 
+0

申し訳ありませんが、これは私の問題を動的に作成されたオブジェクトで解決していません。あなたのアプローチは私のクローン機能にかなり似ています。 –

1

問題は、あなたが「プロトタイプ」

をクローニングする方法である次の行

myBAR.prototype = jQuery.extend(true, myBAR.prototype, this); // deep cloning 

あなただけの「プロトタイプ」をクローニングされていない、あなたはまた、「名前」をクローニングしますプロパティ。

あなたは

myBAR.prototype = jQuery.extend(true, myBAR.prototype, this.prototype); // deep cloning 

でライン上交換した場合はあなたのコードは、今SolutionYogiで言及したことに加えて、行われる必要がある他の変更はあり

new FOO(); // returns FOO:FOO and BAR:BAR 
new BAR(); // returns BAR:BAR 
+1

オブジェクトは既に作成されているので、このプロトタイプは私の場合は未定義のプロパティです。私はthis.prototypeプロパティが初期化された "CLASS"に存在する可能性があることを覚えていません。すでに初期化された "CLASS"からプロトタイプを取得したい場合は、代わりにarguments.callee.prototypeを使用する必要があります。結果的に、現在の動的オブジェクトの代わりに静的オブジェクトのプロトタイプを使用しています。 –

0

を返します。 FOOでは、BARを渡していますが、BARはコンストラクタ(typeof BAR == "function")なので、クローン関数の最初のテストに失敗し、戻り値は変更されていないBARへの参照になります。これは、myBAR.prototypeがBAR.prototypeのクローンではなく、そのリファレンスであることを意味します。

実際に新しいコンストラクタだけではなく、参照を作成するためには、私はあなたがevalのを使用する必要がありますだと思う - のようなものを追加:

if (typeof obj == "function) { 
    eval("var temp = " + obj + ";"); 
    return temp; 
} 

(アレックスが指摘するように)他の考慮事項があります。上記を追加すると、テストケースが成功するはずです。

+0

これは、静的オブジェクトではうまく動作しますが、動的ではありません。 DOM要素への参照があるとします。 –

+0

DOMオブジェクトへの参照を持つBAR(コンストラクタ)を必要とする状況は何ですか? – Rojo

0
function clone(obj) { 
    if(typeof obj !== 'undefined') { 
     clone.prototype = Object(obj); 
     return new clone; 
    } 
} 

function Foo() {} // base class 

function Bar() {} // derived class 
Bar.prototype = clone(Foo.prototype); // inherit from `Foo.prototype` 
+0

申し訳ありませんChristoph同じ問題。私の場合は、バーオブジェクトを動的に拡張する必要があります。 –

関連する問題