js賦值問題


關鍵字:

JS、引用、賦值、對象復制、數組復制等

前言:

//獲取基礎參數列表數據
  getEditTableData(event) {
    if(event&&event.length>0){
      event.forEach(item=>{
        delete item.key
      })
    }
    this.fieldConfDtos=event;
  }

  今天在用angular做父子組件的一些數據傳遞和處理時發現,子組件通過事件傳給父組件的數據被父組件處理后影響到了子組件。event是子組件傳遞過來的參數,這里父組件刪除item.key后,發現子組件數據的key也沒了。查閱資料后發現是對象數組的引用賦值引起的問題。對象賦值問題踩過幾次坑了,這次就系統地記錄一下。

  數據類型:https://www.w3school.com.cn/js/pro_js_value.asp

  1、基礎數據類型:null、undefined、number、string、boolean

  2、對象類型:Object、array、function、data

  簡單結論:基礎數據類型是原始值可以直接賦值、而對象類型是引用賦值只是賦值指針。

解決方法:

  根據實際情況使用淺拷貝或深拷貝。這個內容比較復雜和廣泛,根據具體情況選用合適的方法。參考https://www.cnblogs.com/panrui1994/p/9378696.html。

  常用方法:

  1、Object.assign()

  (1)是對象類型(2)對象的屬性沒有引用類型,即都是基礎數據類型。如{name:'lucy',obj:{sexy:'m',age:'18'}},這種數據里的obj還是引用類型,復制后依然是共用內存。(3)其他使用注意事項參考https://blog.csdn.net/u012028371/article/details/77817059

  2、迭代遞歸法 for...in

  (1)適用范圍為obj和arry,其他特殊類型不行。

// 判斷是否為對象
function isObject(o) {
    return (typeof o === 'object' || typeof o === 'function') && o !== null
}
//測試用例
let test = {
    num: 0,
    str: '',
    boolean: true,
    unf: undefined,
    nul: null,
    obj: {
        name: '我是一個對象',
        id: 1
    },
    arr: [0, 1, 2],
    func: function() {
        console.log('我是一個函數')
    },
    date: new Date(0),
    reg: new RegExp('/我是一個正則/ig'),
    err: new Error('我是一個錯誤')
}
// 迭代遞歸法:深拷貝對象與數組
function deepClone(obj) {
    if (!isObject(obj)) {
        throw new Error('obj 不是一個對象!')
    }
    //判斷傳進來的是對象還是數組
    let isArray = Array.isArray(obj)  
    let cloneObj = isArray ? [] : {}
    //通過for...in來拷貝
    for (let key in obj) {
        cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key]
    }

    return cloneObj
}
let result = deepClone(test)
console.log(result)
//我們發現,arr 和 obj 都深拷貝成功了,它們的內存引用已經不同了,但 func、date、reg 和 err 並沒有復制成功,因為它們有特殊的構造函數。

   

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM