for循环改变原数组( 值引用和地址引用)

 值引用和地址引用

首先我们要明白什么是值引用和地址引用

案例1

const aa={name:'张三'}
let bb=aa
bb={name:'李四'}
console.log('aa',aa);

const aa={name:'张三'}
let bb=aa
bb.name='李四'
console.log('aa',aa);

 由于aa是对象,属于地址引用,当let bb=aa时,bb和aa指向了同一个地址。如果此时改变bb的值,则有两种情况

1)令bb.name='李四',此时会改变aa,而不是创建了一个新的对象,因为他们指向同一个地址

2)令bb={name:'李四'},此时不会改变aa的值,因为创建了一个新的对象,并将该对象的引用赋值给了 bb 。这时 aa 和 bb 指向的是不同的对象,因此修改 bb 不会影响 aa 

案例2

在vue2的data中定义一个对象,然后用计算属性得出一个newP,当改变了newP中的name,我们会发现原始数据person中的数据也发生了改变,这就是因为共用同一个地址导致的

data(){
 return {
      person: {
        name: "张三",
      },
}


 computed: {
    newP() {
      return this.person;
    },
}

  mounted() {
    this.newP.name='李四';
    console.log('newP',this.newP);
    console.log('person',this.person);
  },

注:但是你不能这样写,this.newP={age:18},因为这样相当于是要修改computed的值了,而修改computed的值是需要写set的,否则会报错

当然,该案例还可以深入探讨,比如通过两次计算属性得到的对象,会存在地址引用问题吗?答案是会的,请看第二个小例子:

  data() {
    return {
      obj: {
        name: "张三",
        school: {
          highschool: "北大附中",
          college: "北京大学",
        },
      },
    };
  },

computed:{
  newObj() {
      return this.obj;
    },
    newSchool() {
      return this.newObj.school;
    },
},
  created() {
    this.newSchool.highschool = "清华附中";
    console.log("this.obj", this.obj);
    console.log("this.newObj", this.newObj);
    console.log("this.newSchool", this.newSchool);
  },

案例3

const obj = {
  name: '张三',
  school: {
    highschool: '北大附中',
    college: '北京大学',
  },
};
const changeFn = (option) => {
  option.name = '李四';
  option.school.college='清华大学'
  const { school } = option;

  school.highschool = '清华附中';
  
};
changeFn(obj);
console.log(obj);

我们发现,通过函数更改了对象中的属性值后,再次打印原对象obj时,obj已经发生了改变

案例4

const obj = {
  name: '张三',
  school: {
    highschool: '北大附中',
    college: '北京大学',
  },
};
const changeFn = (option) => {
  let newObj = option;
  newObj.name = '李四';
  newObj.school.college = '清华大学';
  newObj.school.highschool = '清华附中';
  newObj={}
};
changeFn(obj);
console.log(obj);

  • 我们发现,和案例3类似,先把obj赋予给一个newObj,当改变newObj中的属性值时,obj最后同样发生了改变
  • 那为何把newObj设置为空对象时,原始的obj并没有也变成空对象呢?这是因为一旦你执行了newObj={},就意味着给newObj分配了新的地址,因此他和obj就不再指向同一个地址了,因此就不存在引用地址的关系了

 利用for循环改变数组中的值

下面我们再来看数组的两个例子:

const Arr = [
  {
    label: 'Level one 1',
  },
  {
    label: 'Level one 2',
  },
];
for (const i of Arr) {
  console.log(i);
  i.label = 'label改变了';
}
console.log('最终的Arr', Arr);

const Arr2 = [1, 2, 3];
for (let i of Arr2) {
  i = 0;
}
console.log('最终的Arr2', Arr2);

是不是就一目了然啦,如果数组中的value是对象,则可以改变原数组;如果是简单数据类型,就不能改变数组,这就是值引用和地址引用的作用。

猜你喜欢

转载自blog.csdn.net/weixin_48975022/article/details/131878661