Js对象更改

let appState = {
    title: {
        text: 'React.js 小书',
        color: 'red',
    },
    content: {
        text: 'React.js 小书内容',
        color: 'blue'
    }
}
const oldState = appState
console.log(appState)
appState.title.text = '《React.js 小书》';
console.log(oldState !== appState) //false
console.log(oldState != appState) //false

更新了对象的内容,两个对象比较还是相同的,如打印结果,不知怎么理解?

阅读 2.6k
4 个回答

其实不是两个对象的比较,而是引用的比较
ECMAScirpt有五个基本类型(number,string,boolean,null,undefined)和一种引用类型(object)
如果你

var obj1 = {},obj2 = {};  obj1 == obj2 肯定是false
 var n = 1, m = n; n ++ ; n会是2,m还是1

基本类型赋值会在该变量上创建一个新值,m就是n的一个副本
而当一个变量向另一个变量赋值引用类型的值时,与基本类型不同的是,这个值得副本是一个指针,而这个指针指向存储在堆内存中的一个对象,oldState 和 appState都指向同一个内存地址
引用类型占用的空间比较大,所以用指针和变量连接起来
这个经常被误用为拷贝,但是这种 ‘拷贝’ 后,原值会受到影响,所以浅拷贝用 for in去遍历,深拷贝for in + 递归拷贝深层

const oldState = appState;
在将一个值赋给变量时,解析器必须确定这个值是基本类型值还是引用类型
对基本类型,是按值访问的,即通过值复制的方式来赋值和传递。
对引用类型,是按引用访问的,即通过引用复制的方式赋值和传递。在操作对象时,实际上是在操作对象的引用,而不是实际的对象。
所以改变appState 的同时,oldState 也改变了.
对象的比较与基本类型值不同。即使两个对象完全相同,比如两个完全相同的数组,它们也是不相等的。只有两个变量指向同一个对象时,它们才是相等的.

浅拷贝 和 深拷贝的区别
const oldState = {...appState}
console.log(appState)
appState.title.text = '《React.js 小书》';
console.log(oldState !== appState) //false
console.log(oldState != appState) //false

这是引用类型和基本类型的问题,想要结果不一样,建议写一个深拷贝

//参数p为原对象
//参数c为原对象的类型,若原对象为数组,则传入c为[],若原对象是对象传入c为{},也可不传默认为{}
function deepCopy(p,c){
var c = c || {};
for(var i in p){
  if(typeof p[i] === "object"){
    c[i] = (p[i].constructor === Array)?[]:{};
    deepCopy(p[i],c[i])
    }else{
    c[i] = p[i]
   }
  }
  return c;
}
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题