@@ -93,7 +93,7 @@ function serializeJavascriptRecursively(
9393 return `${ ST } new RegExp('${ source . source . replace ( / \\ \\ / g, '\\' ) } ', '${ source . flags ?? '' } ')${ ET } ` ;
9494 // `value instanceof Date` never works, try testing date format instead
9595 } else if ( source instanceof Date ) {
96- return `${ ST } new Date('${ source . getTime ( ) } ')${ ET } ` ;
96+ return `${ ST } new Date('${ source . toISOString ( ) } ')${ ET } ` ;
9797 } else if ( typeof source === 'bigint' ) {
9898 return `${ ST } BigInt('${ source . toString ( ) } ')${ ET } ` ;
9999 } else if ( typeof source === 'symbol' ) {
@@ -114,8 +114,7 @@ function serializeJavascriptRecursively(
114114 } ;
115115 if ( typeof source === 'object' ) {
116116 if ( checkCircularRef ( ) ) return undefined ;
117- // todo: 展开原型链,获取所有属性和方法
118- // todo: 处理 Map、Set、WeakMap、WeakSet、ArrayBuffer、DataView、Blob 等特殊对象
117+ // todo: 修复e2e测试
119118 // todo: 优先判断对象是否有toJson()方法
120119 // todo: parse时,需要判断是否有fromJson()方法,如果有,则调用该方法进行反序列化
121120 /*
@@ -434,7 +433,6 @@ function getDeserializeJavascriptCode(result: SerializedResult, options: Interna
434433 return content ;
435434}
436435
437- // todo: 序列化改成深度递归,不适用JSON.stringify。expandPrototypeChain改为在序列化过程中调用,避免修改源对象,也避免尝试构造源对象的副本
438436/**
439437 * Expands the prototype chain of the source object, including all properties from the prototype
440438 * chain.
@@ -482,10 +480,16 @@ function expandPrototypeChainRecursively(
482480 if ( Array . isArray ( source ) ) {
483481 result = [ ...source ] ;
484482 } else if ( source instanceof Map ) {
485- result = new Map ( source ) ;
483+ result = Array . from ( source . keys ( ) ) . reduce (
484+ ( acc , key ) => {
485+ acc [ key ] = source . get ( key ) ;
486+ return acc ;
487+ } ,
488+ { } as Record < any , any >
489+ ) ;
486490 types . push ( { path : paths , type : 'Map' } ) ;
487491 } else if ( source instanceof Set ) {
488- result = new Set ( source ) ;
492+ result = Array . from ( source ) ;
489493 types . push ( { path : paths , type : 'Set' } ) ;
490494 } else if ( source instanceof WeakMap ) {
491495 result = { } ;
@@ -508,7 +512,8 @@ function expandPrototypeChainRecursively(
508512
509513 // Expand prototype properties to newSource
510514 const proto = pickPrototype ( source , options ) ;
511- const protoDescriptors = Object . getOwnPropertyDescriptors ( proto ) ;
515+ const destWithProto = pickPrototype ( result ) ;
516+ const destDescriptors = Object . getOwnPropertyDescriptors ( destWithProto ) ;
512517 const checkDescriptor = ( key : keyof any , descriptor : PropertyDescriptor ) => {
513518 if (
514519 descriptor &&
@@ -530,24 +535,31 @@ function expandPrototypeChainRecursively(
530535 } ) ;
531536 }
532537 } ;
533- getFullKeys ( proto ) . forEach ( ( key ) => {
534- const descriptor = protoDescriptors [ key ] ;
535- // If the descriptor is not readable, skip it
536- if ( ! descriptor || 'value' in descriptor ) {
537- result [ key ] = proto [ key ] ;
538- }
539- checkDescriptor ( key , descriptor ) ;
540- } ) ;
541- const sourceDescriptors = Object . getOwnPropertyDescriptors ( source ) ;
542- // copy own properties to newSource
543- getFullKeys ( source ) . forEach ( ( key ) => {
544- const descriptor = sourceDescriptors [ key as string ] ;
545- // If the descriptor is not readable, skip it
546- if ( ! descriptor || 'value' in descriptor ) {
547- result [ key ] = source [ key ] ;
548- }
549- checkDescriptor ( key , descriptor ) ;
550- } ) ;
538+ const assign = ( source : Record < string | symbol , any > ) => {
539+ const sourceDescriptors = Object . getOwnPropertyDescriptors ( proto ) ;
540+ getFullKeys ( source ) . forEach ( ( key ) => {
541+ const descriptor = sourceDescriptors [ key ] ;
542+ const destDescriptor = destDescriptors [ key as string ] ;
543+ // If the descriptor is not readable, skip it
544+ if ( descriptor && ! descriptor . get && ! ( 'value' in descriptor ) ) {
545+ return ;
546+ }
547+ // If the destination descriptor is not writable, skip it
548+ if ( destDescriptor && ! destDescriptor . writable && ! ( 'value' in destDescriptor ) ) {
549+ return ;
550+ }
551+ try {
552+ result [ key ] = source [ key ] ;
553+ } catch ( error ) {
554+ // not raise error
555+ }
556+ checkDescriptor ( key , descriptor ) ;
557+ } ) ;
558+ } ;
559+
560+ assign ( proto ) ;
561+ assign ( source ) ;
562+
551563 for ( const key of getFullKeys ( result ) ) {
552564 result [ key ] = expandPrototypeChainRecursively ( result [ key ] , {
553565 ...options ,
0 commit comments