クローン関数をjavascriptで書いています。
その関数はオブジェクトを再帰的に複製し(循環参照を回避)、うまく機能しているように見えますが、オブジェクト(あるレベルで)にオブジェクト参照が組み込まれている場合、複製されたオブジェクトのプロパティ(正しいように見えます)にアクセスしようとすると、タイプエラー。
これは、datetime を使用した私の簡単な例です (datetime オブジェクトをクローンするためのより効率的な方法があることは知っていますが、それは私の関心事ではありません。私がする必要があるのは、一般的なビルド オブジェクトを複製することです。datetimes は単なる例です)。関数と配列のみをシャローコピーし、オブジェクト(内部配列と関数を除く)をディープコピーし、循環参照を回避しないメソッドへのメソッド。これはエラーの説明にすぎません (完全なクローン機能で得られるのと同じエラーです)。
コード :
var date = new Date () ;
var dateProto = date.__proto__ ;
var cloned = {} ;
var clonedProto = {} ;
function clone ( obj )
{
if ( obj instanceof Array )
return [] ;
if ( obj instanceof Function )
return obj ;
if ( obj instanceof Object )
{
var result = {} ;
var elems = Object.getOwnPropertyNames(obj) ;
var len = elems.length ;
for ( var i = 0 ; i < len ; i++ )
{
var prop = elems[i] ;
var elem = obj[prop] ;
result [ prop ] = clone ( elem ) ;
}
return result ;
}
return obj ;
}
cloned = clone ( date ) ;
clonedProto = clone ( dateProto ) ;
cloned.__proto__ = clonedProto ;
alert ( cloned.getDay() );
しかし、これにより getDay メソッドにアクセスしようとすると、この型エラーが発生します: Uncaught TypeError: this is not a Date object.
しかし、私はまだ理由を理解していません.クローンが日付オブジェクトのように見える. "クローン") ですが、エラーではありません。
では、なぜこのエラーが発生するのでしょうか?
助けてくれてありがとう、私の悪い英語でごめんなさい。
編集済み
提案された新しいアイデア (コメントで jfriend00 によって投稿されたフォーム RobG とフォーム記事の両方) に従って、クローン関数 i をそのように書き直しました。
function clone ( obj )
{
if ( obj instanceof Array )
return [] ;
if ( obj instanceof Function )
return obj ;
if ( obj instanceof Object )
{
var result = new obj.constructor() ;
result.__proto__ = clone ( obj.__proto__ ) ;
var elems = Object.getOwnPropertyNames(obj) ;
var len = elems.length ;
for ( var i = 0 ; i < len ; i++ )
{
var prop = elems[i] ;
var elem = obj[prop] ;
result [ prop ] = clone ( elem ) ;
}
return result ;
}
return obj ;
}
期待どおりに動作するようになりましたが、このコードの理由がわかりません: var result = new obj.constructor() ; 差をつける。
助けてくれてありがとう。