NodeJS中传递数组至函数时原数组被修改的问题及需求
问题分析与解决
JS里数组属于引用类型,当你把数组传给函数,或是把函数参数赋值给临时变量时,本质只是复制了一份内存地址——两个变量指向的是同一块内存里的对象。所以修改临时变量的属性,其实就是在修改原数组的属性,这就是原数组被改动的原因。
要让原数组不受任何修改影响,你需要创建原对象的浅拷贝副本,修改副本就不会牵连原对象了。针对你的场景,有几种简单的实现方式:
方法1:用Object.assign()创建副本
Object.assign()会把原对象的所有可枚举属性复制到新对象里,因为数组本身也是对象,这个方法能直接拷贝包括自定义text在内的所有属性:
function abc(data) { console.log("1. " + data.text); // 创建原数组的浅拷贝副本 var tempss = Object.assign([], data); console.log("2. " + tempss.text); tempss.text = 20; console.log("3. " + data.text); console.log("4. " + tempss.text); } let a = new Array(); a.text = 3; abc(a); console.log("5. " + a.text);
方法2:用展开运算符...创建副本
展开运算符可以快速复制数组的索引元素,但自定义的非索引属性(比如你加的text)不会自动拷贝,需要手动赋值:
function abc(data) { console.log("1. " + data.text); // 复制数组的索引元素 var tempss = [...data]; // 手动复制自定义属性 tempss.text = data.text; console.log("2. " + tempss.text); tempss.text = 20; console.log("3. " + data.text); console.log("4. " + tempss.text); } let a = new Array(); a.text = 3; abc(a); console.log("5. " + a.text);
方法3:手动创建副本并复制属性
如果场景简单,也可以直接创建新数组,再把需要的属性和元素复制过去:
function abc(data) { console.log("1. " + data.text); var tempss = []; // 复制自定义属性 tempss.text = data.text; // 如果数组里有元素,也需要复制,比如:tempss.push(...data); console.log("2. " + tempss.text); tempss.text = 20; console.log("3. " + data.text); console.log("4. " + tempss.text); } let a = new Array(); a.text = 3; abc(a); console.log("5. " + a.text);
以上方法运行后,都会得到你期望的输出:
1. 3 2. 3 3. 3 4. 20 5. 3
内容的提问来源于stack exchange,提问作者huso
相关产品推荐
相关产品推荐

