conlose.log() (2)

274 阅读2分钟
let a = {
  name: 'lee',
  age: 18
}
let b = a;
console.log(a.name);  //第一个console  'lee'
b.name = 'son';
console.log(a.name);  //第二个console   'son'
console.log(b.name);  //第三个console   'son'

执行了 b.name='son' 之后,第二个和第三个打印结果是一样的,体现了引用类型的“共享”的特性,即这两个值都存在同一块内存中共享,一个发生了改变,另外一个也随之跟着变化。

let a = {
  name: 'Julia',
  age: 20
}

function change(o) {
  o.age = 24;
  o = {
    name: 'Kath',
    age: 30
  }
  return o;
}

let b = change(a);     
console.log(b);    // 第一个console  {name: "Kath", age: 30}
console.log(a);    // 第二个console  {name: "Julia", age: 24}

注意,这里的 function 和 return 带来了不一样的东西。

原因在于:函数传参进来的 o,传递的是对象在堆中的内存地址值,通过调用 o.age = 24改变了 a 对象的 age 属性;return语句把参数 o 的地址重新返回了,将 {name: "Kath", age: 30} 存入其中,最后返回 b 的值就变成了 {name: "Kath", age: 30}。而如果把return语句去掉,那么 b 就会返回 undefined。因为这个function没有返回值。

补充:b是返回值,就是function里返回的那个o。change()只是改变传入对象的年龄,同时返回一个对象,有变量接收则赋值给接收对象了。 不管b是什么,只要把change赋值给他,b就是那个o的引用,和a没关系。函数赋值得到的东西就是return里面的,没有return就是undefined。

  • 这样理解,传进来的o它是一个引用,改变age是改变属性,赋值一个新的对象给它就是改变了它的引用。(对象的赋值改变引用)
  • 属性的赋值,.age,就是取到了对应的元素,直接改它的值
  • 如果 . 前面的是对象,那改变的是引用(可以延伸到深浅拷贝的一种理解)
  • 可以在o赋值为对象前后打印一下o,发现它的变化
let a = {
    name: 'Julia',
    age: 20
  }
  
  function change(o) {
    console.log("1:", o)   // { name: 'Julia', age: 20 }
    o.age = 24;
    console.log("2:", o);  // { name: 'Julia', age: 24 }
    o = {
      name: 'Kath',
      age: 30
    }
    console.log("3:", o);  // { name: 'Kath', age: 30 }
    return o;
  }
   
change(a);  
console.log("a:", a);  // { name: 'Julia', age: 24 }
let b = change(a);     
console.log("b:", b);  // { name: 'Kath', age: 30 }

//2和a是同一个地址,3和b也是同一个地址。

image.png
这两个o不是同一个o,传进来的o指向a的地址,

621c6b1be7bf5599a8bbb990e6862bf.png
执行了这个,这个o就不是传进来的那个o了,这个地址就是这个对象。