1+ <!DOCTYPE html>
2+ < html lang ="en ">
3+
4+ < head >
5+ < meta charset ="UTF-8 ">
6+ < meta name ="viewport " content ="width=device-width, initial-scale=1.0 ">
7+ < meta http-equiv ="X-UA-Compatible " content ="ie=edge ">
8+ < title > 对象的深拷贝</ title >
9+ < style >
10+ * {
11+ margin : 0 ;
12+ padding : 0 ;
13+ }
14+
15+ h1 {
16+ text-align : center;
17+ }
18+
19+ h2 ,
20+ h4 {
21+ line-height : 50px ;
22+ text-align : center;
23+ }
24+
25+ section {
26+ padding : 50px ;
27+ }
28+ </ style >
29+ </ head >
30+
31+ < body >
32+ < h1 > 对象的深拷贝 structuredClone </ h1 >
33+ < hr >
34+
35+ < section >
36+ < h2 > structuredClone() API是结构化克隆算法进行深拷贝(支持大部分数据类型,但不支持函数和Symbol)</ h2 >
37+ < h4 > 深拷贝是指创建一个对象的完全独立副本,副本与原始对象在内存中是不同的引用,修改副本不会影响原始对象。深拷贝通常需要递归地复制对象的所有属性和嵌套对象。</ h4 >
38+ </ section >
39+
40+ < script >
41+
42+ //数组或对象的深拷贝方法2
43+ const deepCopy = ( val ) => {
44+ let oVal = Array . isArray ( val ) ? [ ] : { } ;
45+ for ( let v in val ) {
46+ if ( val . hasOwnProperty ( v ) ) {
47+ if ( 'object' === typeof val [ v ] ) {
48+ // 这里是深拷贝的关键所在(递归调用)
49+ oVal [ v ] = deepCopy ( val [ v ] ) ;
50+ } else {
51+ oVal [ v ] = val [ v ] ;
52+ } ;
53+ }
54+ } ;
55+ return oVal ;
56+ } ;
57+
58+ const deepClone = ( obj , hash = new WeakMap ( ) ) => {
59+ if ( obj === null ) return null ;
60+ if ( obj instanceof Date ) return new Date ( obj ) ;
61+ if ( obj instanceof RegExp ) return new RegExp ( obj ) ;
62+ if ( typeof obj !== "object" ) return obj ;
63+ if ( hash . has ( obj ) ) return hash . get ( obj ) ; // 处理循环引用
64+ let clone = Array . isArray ( obj ) ? [ ] : { } ;
65+ hash . set ( obj , clone ) ; // 在拷贝前存储原始对象和其对应的克隆对象的关系
66+ for ( let key in obj ) {
67+ if ( obj . hasOwnProperty ( key ) || isObject ( key ) ) {
68+ clone [ key ] = deepClone ( obj [ key ] , hash ) ;
69+ }
70+ }
71+ return clone ;
72+ }
73+
74+
75+
76+ //对象数组深拷贝测试
77+ let obj = { h5 : 'H5' , cs : 'CSS' , back : { a : 'PHP' , b : 'Java' , c : [ 'A' , 'B' , [ '一' , 2 , '三' ] , 3 , { d : '3D' } ] } , js : 'ES6' , null : null , nan : NaN , undefined : undefined , infinity : Infinity , regexp : / [ a - z A - Z 0 - 9 _ ] / g, symbol : Symbol ( '' ) , fun : function ( e ) { console . log ( 666 ) } } ;
78+
79+ let nObj = deepCopy ( obj ) ;
80+ nObj . back . c [ 0 ] = 'AAA' ;
81+ nObj . back . c [ 2 ] [ 0 ] = '壹' ;
82+ nObj . back . c [ 2 ] [ 2 ] = '叁' ;
83+ nObj . fn = function ( abc ) {
84+ alert ( 888 )
85+ }
86+ console . log ( '修改前:' , obj ) ;
87+ console . log ( '修改后1:' , nObj ) ;
88+
89+ let nObj2 = deepClone ( obj ) ;
90+ console . log ( '修改后2:' , nObj2 ) ;
91+
92+ // 使用structuredClone结构化克隆算法进行深拷贝(支持大部分数据类型,但不支持函数和Symbol)
93+ let nObj3 = structuredClone ( obj ) ;
94+ console . log ( '修改后3:' , nObj3 )
95+ </ script >
96+ </ body >
97+
98+ </ html >
0 commit comments