两种常用SuperObject的遍历

本文展示了如何使用ISuperObject解析Memo1中的数据,通过`SO`函数将文本转换为对象,并使用循环逐个提取item的信息,包括名称和值。实例演示了如何将数据以JSON格式输出到Memo2中。
memo1.text := {"MYGUID":"s3","存款金额":30000.,"规格表示":null}
例子1:
var
 item, jo: ISuperObject;
begin
  jo := SO(Memo1.Text);
  for item in jo do
  begin
    Memo2.Lines.Add(item.AsJSon(False, False));
  end;
end;
例子2:
var
  jo: ISuperObject;
  item: TSuperAvlEntry;
begin
  jo := SO(Memo1.Text);
  for item in jo.AsObject do
  begin
    Memo2.Lines.Add(item.name);
    Memo2.Lines.Add(item.value.AsString);
  end;
end;

 

<think> 我们正在讨论浅拷贝和深拷贝的常用方法。根据用户提供的引用,我们可以总结如下: ### 浅拷贝常用方法: 1. **Object.assign()** (JavaScript): 用于将所有可枚举属性的值从一个或多个源对象复制到目标对象,并返回目标对象。执行的是浅拷贝。 示例: ```javascript const obj1 = { a: 1, b: { c: 2 } }; const obj2 = Object.assign({}, obj1); obj1.b.c = 3; console.log(obj2.b.c); // 输出3,因为b是引用类型,共享同一内存 ``` 2. **数组的slice()方法** (JavaScript): 返回一个新的数组对象,这一对象是一个由原数组的浅拷贝。 示例: ```javascript const arr1 = [1, 2, [3, 4]]; const arr2 = arr1.slice(); arr1[2][0] = 5; console.log(arr2[2][0]); // 输出5,因为内部数组是引用类型,共享同一内存 ``` 3. **数组的concat()方法** (JavaScript): 用于合并两个或多个数组,返回一个新数组,也是浅拷贝。 示例: ```javascript const arr1 = [1, 2, [3, 4]]; const arr2 = [].concat(arr1); arr1[2][0] = 5; console.log(arr2[2][0]); // 输出5 ``` 4. **展开运算符(...)** (JavaScript ES6): 可以在构造字面量对象或数组时展开属性,实现浅拷贝。 示例: ```javascript const obj1 = { a: 1, b: { c: 2 } }; const obj2 = { ...obj1 }; obj1.b.c = 3; console.log(obj2.b.c); // 输出3 const arr1 = [1, 2, [3, 4]]; const arr2 = [...arr1]; arr1[2][0] = 5; console.log(arr2[2][0]); // 输出5 ``` 5. **直接赋值** (多种语言): 在Java等语言中,直接赋值操作(如`Object obj2 = obj1;`)实际上是复制引用,因此也是浅拷贝(严格来说,它只是创建了一个新的引用指向同一个对象,但通常也归为浅拷贝的一种形式)。 ### 深拷贝常用方法: 1. **递归复制**: 手动实现递归函数,遍历对象的每个属性,如果是基本类型则直接复制,如果是引用类型则递归复制。 示例(JavaScript): ```javascript function deepCopy(obj) { if (typeof obj !== 'object' || obj === null) { return obj; } const newObj = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = deepCopy(obj[key]); } } return newObj; } ``` 2. **JSON.parse(JSON.stringify())** (JavaScript): 利用JSON的序列化和反序列化实现深拷贝。但这种方法有局限性: - 不能复制函数(函数会被忽略) - 不能复制`undefined`(会丢失) - 不能复制正则表达式(会变成空对象) - 不能复制日期对象(会变成字符串) - 循环引用会报错 示例: ```javascript const obj1 = { a: 1, b: { c: 2 } }; const obj2 = JSON.parse(JSON.stringify(obj1)); obj1.b.c = 3; console.log(obj2.b.c); // 输出2,说明是深拷贝 ``` 3. **使用第三方库**: 例如在JavaScript中,可以使用`lodash`库的`_.cloneDeep()`方法。 示例: ```javascript const _ = require('lodash'); const obj1 = { a: 1, b: { c: 2 } }; const obj2 = _.cloneDeep(obj1); ``` 4. **Java中的深拷贝实现**: - 实现`Cloneable`接口并重写`clone()`方法,在重写时需要递归调用引用类型属性的`clone()`方法。 示例: ```java class Address implements Cloneable { private String city; // 构造方法、getter/setter省略 @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class Person implements Cloneable { private String name; private Address address; // 构造方法、getter/setter省略 @Override protected Object clone() throws CloneNotSupportedException { Person cloned = (Person) super.clone(); cloned.address = (Address) address.clone(); // 递归克隆引用类型 return cloned; } } ``` - 通过序列化实现:将对象写入流中再从流中读取,这样会创建一个全新的对象。 示例: ```java import java.io.*; public class DeepCopyUtil { public static <T extends Serializable> T deepCopy(T object) { try (ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos)) { oos.writeObject(object); try (ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis)) { return (T) ois.readObject(); } } catch (Exception e) { throw new RuntimeException(e); } } } ``` 5. **其他语言**: 在Python中可以使用标准库的`copy`模块: - 浅拷贝:`copy.copy()` - 深拷贝:`copy.deepcopy()` ### 注意事项: - **浅拷贝**只复制一层,适合对象结构简单或不需要嵌套复制的情况,性能较高。 - **深拷贝**复制整个对象结构,适合对象结构复杂且需要完全独立副本的情况,但性能较低,且需要注意循环引用的问题。 ### 总结表格: | 方法类型 | 常用实现方式 | 特点 | |----------|----------------------------------|----------------------------------------------------------------------| | 浅拷贝 | Object.assign() | 仅复制一层,嵌套对象共享引用 | | | 数组的slice()、concat() | 数组浅拷贝,嵌套数组共享引用 | | | 展开运算符(...) | 对象或数组的浅拷贝 | | | 直接赋值 | 复制引用,指向同一对象 | | 深拷贝 | JSON.parse(JSON.stringify()) | 简单但有限制(忽略函数、undefined等) | | | 递归复制 | 可自定义,但需处理循环引用和复杂类型 | | | 第三方库(如lodash.cloneDeep) | 功能强大,支持复杂类型和循环引用 | | | Java中Cloneable接口重写clone() | 需要递归调用引用类型的clone方法 | | | Java中的序列化方法 | 对象需实现Serializable接口,性能较低但通用 | | | Python的copy.deepcopy() | 标准库提供,支持大多数类型的深拷贝 | ### 引用说明: - 引用[1]提到JSON方法实现深拷贝的局限性(不能复制函数、正则等)[^1]。 - 引用[2]和[4]总结了浅拷贝常用方法(如Object.assign)[^2][^4]。 - 引用[3]解释了浅拷贝在Java中的概念(仅复制基本类型和引用,共享引用指向的对象)[^3]。 ### 相关问题: §§相关问题§§ 1. 在JavaScript中,使用JSON.parse(JSON.stringify())进行深拷贝有哪些局限性?如何处理这些局限性? 2. 如何用递归实现一个支持循环引用的深拷贝函数? 3. 在Java中,使用序列化实现深拷贝有什么优缺点?适用于哪些场景? [^1]:深拷贝和浅拷贝的几种方法。深拷贝最简单的方法: 最简单的方法就是JSON.parse(JSON.stringify()) function deepCopy(o) { return JSON.parse(JSON.stringify(o)) } var c = { age: 1, name: undefined, sex: null, tel: /^1[34578]\d{9}$/, say: () => { console.log('hahha') } } // { age: 1, sex: null, tel: {} } 需要注意的是:这种拷贝方法不可以拷贝一些特殊的属性(例如正则表达式,undefine,function) [^2]:深拷贝和浅拷贝开发常用方法总结。在前端开发的工作中经常需要对数据进行处理,这时候会经常使用到浅拷贝和深拷贝先拷贝原有数据再进行处理,以下就是常用的方法总结,我将以代码的形式来带大家去使用和理解这些方式 一、浅拷贝常用方法 1. Object.assign [^3]:java,深拷贝和浅拷贝。浅拷贝是指仅拷贝对象的基本类型字段和引用类型字段的引用,而不是引用类型所指向的对象本身。因此,浅拷贝后的对象与原对象的引用类型字段共享相同的对象。如果原对象或拷贝对象中的引用类型被修改,两个对象都会受到影响。 实现方式 [^4]:深拷贝浅拷贝方法总结。 如果属性是基本类型,则为值传递,如果属性是引用类型则拷贝内存地址,即共用内存地址,改变任意一个则另一个内存地址指向也变化。 2.实现方法 Object.assign(target,…source)Array.prototype.slice()Array.prototype.concat() 2.1 Object.assign(target,…source) var obj1 = { name : 'ggg', age : 18, sex : '女', stu : { name :'mmm' } } var obj2 = Object.assign({},obj1) console.log(obj2) obj1.name = 'hhh'; obj2.stu.name = 'kkk'; console.log(obj1); console.log(obj2); </think> ### 常用的浅拷贝和深拷贝方法总结 #### 一、浅拷贝常用方法(仅复制一层数据结构) 1. **Object.assign()** JavaScript 中最常用的浅拷贝方法,复制对象的可枚举属性 ```javascript const obj2 = Object.assign({}, obj1); ``` 特点: - 仅拷贝对象的第一层属性 - 嵌套对象仍共享内存地址 - 修改嵌套属性会影响原始对象[^4] 2. **数组的 slice() 方法** 创建数组的浅副本 ```javascript const newArr = originArr.slice(); ``` 3. **数组的 concat() 方法** 合并数组时创建新数组 ```javascript const newArr = [].concat(originArr); ``` 4. **展开运算符 (...)** ES6 提供的简洁语法 ```javascript const obj2 = { ...obj1 }; const arr2 = [...arr1]; ``` 5. **手动遍历赋值** 基础实现原理: ```javascript function shallowCopy(obj) { const newObj = {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = obj[key]; } } return newObj; } ``` #### 二、深拷贝常用方法(递归复制所有层级) 1. **JSON 序列化方法** 最简便但有限制的深拷贝: ```javascript const deepCopy = JSON.parse(JSON.stringify(obj)); ``` **局限性**: - 无法拷贝函数(丢失) - 无法拷贝正则表达式(变为空对象) - 无法拷贝 `undefined`(丢失) - 无法拷贝循环引用(报错)[^1] 2. **递归复制函数** 手动实现完整深拷贝: ```javascript function deepClone(obj) { if (typeof obj !== 'object' || obj === null) return obj; const result = Array.isArray(obj) ? [] : {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { result[key] = deepClone(obj[key]); } } return result; } ``` 3. **第三方库实现** 推荐使用成熟工具库: ```javascript // lodash import _ from 'lodash'; const copy = _.cloneDeep(obj); // jQuery const copy = $.extend(true, {}, obj); ``` 4. **MessageChannel API** 利用浏览器 API 实现异步深拷贝: ```javascript function deepCopy(obj) { return new Promise(resolve => { const { port1, port2 } = new MessageChannel(); port2.onmessage = ev => resolve(ev.data); port1.postMessage(obj); }); } ``` 5. **结构化克隆算法** HTML5 新特性(适用于浏览器环境): ```javascript const copy = structuredClone(obj); ``` #### 三、各语言实现对比 | 语言 | 浅拷贝方法 | 深拷贝方法 | |-----------|-----------------------------------|-------------------------------------| | **JavaScript** | `Object.assign()`, `slice()`, `...` | `JSON.parse/stringify`, `lodash.cloneDeep` | | **Python** | `copy.copy()` | `copy.deepcopy()` | | **Java** | 实现`Cloneable`接口(默认浅拷贝) | 序列化/手动递归复制引用对象 | | **C++** | 默认拷贝构造函数 | 重写拷贝构造函数实现递归复制 | #### 四、选择建议 - **优先浅拷贝**:当对象无嵌套引用或性能敏感时使用 - **必须深拷贝**: - 对象包含嵌套可变数据结构 - 需要隔离修改的场景(如状态管理) - 涉及多线程/并发的环境 > **重要提示**:深拷贝的成本随对象复杂度指数级增长,对于大型对象需谨慎使用[^2][^3]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值