js小拔高系列——寫一個深拷貝

最近想全職當碼農,面試時候被問到了深拷貝,我噼裏啪啦說了一通,感覺很牛逼,問我自己寫過沒有,我說沒有,但是我可以寫。其實我很心虛,估計現場寫會卡殼。。。。。

思路

  • 深拷貝需要迭代拷貝對象的所有屬性,如果屬性是引用型:Object,則繼續遞歸迭代。

實現

  • 首先可以寫一個殼子函數,包裹一個將要反覆遞歸調用自身的函數。

    function deepCopy(obj) {
        const handleDeepCopy = obj=>{
           const clonedObj = obj instanceof Array? []:{}
          return clonedObj
        }
        return handleDeepCopy(obj)
    }

    clonedObj就是即將克隆返回的新對象
    今後會這麼使用它:let newobj = deepCopy(oldobj)
    newobj就是經過深拷貝的新對象,這樣在操作newobj的時候就不會對oldobj產生干擾了

  • 接着完善遞歸拷貝邏輯。

    1. 用for in迭代數組和對象的屬性。(若不用forin迭代,用foreach代碼會比較多,數組和對象的處理方式會有所不同)
    2. 判斷屬性的類型,是否是引用型。
    3. 如果是引用型,將clonedObj對應的property賦值爲handleDeepCopy(obj[property])【遞歸拷貝】。
    4. 如果不是引用型,直接將clonedObj對應的property賦值爲obj[property]。

      function deepCopy(obj) {
          const handleDeepCopy = obj=>{
             const clonedObj = obj instanceof Array? []:{}
            // add for in logic here
            for (let keyOrIndex in obj) {
                if(obj[keyOrIndex] instanceof Object) {
                    clonedObj[keyOrIndex] = handleDeepCopy(obj[keyOrIndex])
                } else {
                    clonedObj[keyOrIndex] = obj[keyOrIndex]
                }
            }
            // for in logic over
            return clonedObj
          }
          return handleDeepCopy(obj)
      }
  • 以上邏輯還有疏忽的地方,沒有在開始時判斷傳進的obj究竟是不是一個引用型,如果不是,就應該直接將obj返回。另外在for in中需要使用hasOwnProperty進行判斷,因爲我們只想拷貝obj自身的屬性。爲了節約篇幅,增加以上邏輯後修改的代碼在:stackblitz
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章