關於傳參對象屬性修改,源對象保持不變

案例

let obj = { // 對象
  name: 'father',
  person: {
    name: 'son',
    age: 18
  }
}
function change(param) {
  param.person.name = 'didi'
}
console.log(obj) // { name: 'father', person: { name: 'son', age: 18 } } 
change(obj)
console.log(obj) // { name: 'father', person: { name: 'didi', age: 18 } }

上面的案例中只是把obj當參數傳遞給change方法,但是發覺在change方法裏面的參數param改變了person的屬性,obj對象裏面的person屬性也會相應的改變。可以得出即使obj作爲參數,被方法調用,也會改變對象裏面的數值。

解決方案

裏面的原理和對象的地址指向問題有關,這裏證明了即使是作爲參數,他們指向的堆的地址也是一致的。因爲可以使用改變堆地址的方式解決

  1. 方案一深拷貝:
let obj = { // 對象
  name: 'father',
  person: {
    name: 'son',
    age: 18
  }
}

function change(param) {
  let obj1 = {}; // 空對象
  deepCopy(param, obj1) // 深拷貝
  console.log(obj1) // { name: 'father', person: { name: 'son', age: 18 } }
  obj1.person.name = 'didi'
  console.log(obj1) // { name: 'father', person: { name: 'didi', age: 18 } }
}
function deepCopy(o1, o2) {
      for (var key in o1) {
        // 獲取key屬性對應的值
        var item = o1[key];
        // 如果item 是對象?
        // var o = {}
        if (item instanceof Object) {
          // var o = {};
          o2[key] = {}; 
          deepCopy(item, o2[key]);
        } else if (item instanceof Array) {
          // 如果item 是數組呢?
          // var arr = [];
          o2[key] = [];
          deepCopy(item, o2[key]);
        } else {
          // 如果是簡單類型
          o2[key] = o1[key];
        }
      }
    }
console.log(obj) // { name: 'father', person: { name: 'son', age: 18 } }
change(obj)
console.log(obj) // { name: 'father', person: { name: 'son', age: 18 } }
  1. 方案二 JSON.parse(JSON.stringify())
let obj = { // 對象
  name: 'father',
  person: {
    name: 'son',
    age: 18
  }
}

function change(param) {
  let obj1 = JSON.parse(JSON.stringify(param)); // JSON對象轉換
  console.log(obj1) // { name: 'father', person: { name: 'son', age: 18 } }
  obj1.person.name = 'didi'
  console.log(obj1) // { name: 'father', person: { name: 'didi', age: 18 } }
}

console.log(obj) // { name: 'father', person: { name: 'son', age: 18 } }
change(obj)
console.log(obj) // { name: 'father', person: { name: 'son', age: 18 } }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章