这个问题在这里已有答案:
我对js'delete'运算符感到困惑。
例如
var data = {
list : [a, b, c]
}
var temp = data;
console.log(temp.list[2]); //Result 'c'
console.log(data.list[2]); //Result 'c'
delete temp.list[2];
console.log(temp.list[2]); //Result undefined
console.log(data.list[2]); //Result undefined why?
在这种情况下,我刚刚删除了temp.list[2]
,但data.list[2]
也显示未定义。
'删除'运算符跟踪数组地址并删除其中的数据?这就是为什么data.list[2]
也未定义? (因为data.list[2]
有地址,而不是实际数据本身)我认为有解释。你能帮助我吗?
参考类型
var data = [] ==> instance
var temp = data; ==> data reference
get temp ==> return data
// shallow copy !!!
var temp = Object.assign([], data); ===> instance
console.log(temp.list[2]); //Result undefined
console.log(data.list[2]); //Result c
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
查看其他人发布的所有精彩参考文献。但是对于快速解决方案,请使用ES6扩展运算符来创建副本。
var data = {
list : ["a", "b", "c"]
}
var temp = {...data}; // this is now a copy not a reference
换句话说,这不是删除问题,它是引用与复制问题
JS中的复杂类型通过引用传递,除非您明确地处理它们。
这里发生的事情是:
var data = { // <--\
list : [a, b, c] // <----------------------------------------------
} // <--/ |
var temp = data; // this is NOT a copy, but literally a pointer to -/
尝试
var temp = Object.assign({}, data);
如果你想要一份副本。
您的问题涉及几个主题:
首先,delete运算符从对象中删除给定属性,但是当用于从数组中删除元素时,数组长度不受影响:
let trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
delete trees[3];
alert(trees.length); //shows 5
如果这不是您想要的,请考虑使用splice方法。它非常强大,不仅可以用于删除元素。
let trees = ['redwood', 'bay', 'cedar', 'oak', 'maple'];
trees.splice(3, 1);
alert(trees.length); //shows 4
其次,正如大家已经提到的那样,var temp = data;
不会创建对象的副本,它只是复制引用。要创建对象的完全相同的浅层克隆,您可以编写:
let clone = Object.create(Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj));
这个调用是一个真正精确的obj副本,包括所有属性:可枚举和不可枚举,数据属性和setter / getters - 所有内容,以及正确的[[Prototype]]
,当Object.assign()
方法只复制可枚举和自己的属性从源对象到目标对象