js 對象克隆方法總結(不改變原對象)


1.通用對象克隆:

function clone(obj){
    let temp = null;
    if(obj instanceof Array){
        temp = obj.concat();
    }else if(obj instanceof Function){
        //函數是共享的是無所謂的,js也沒有什么辦法可以在定義后再修改函數內容
        temp = obj;
    }else{
        temp = new Object();
        for(let item in obj){
            let val = obj[item];
            temp[item] = typeof val == 'object'?clone(val):val; //這里也沒有判斷是否為函數,因為對於函數,我們將它和一般值一樣處理
        }
    }
    return temp;
}

整個clone函數的思路可能有點亂,但是可以這樣理順:

把obj的value當做只有普通值、數組和函數,先按部就班地處理,然后再考慮之前的“普通值”有可能是object,所以這里做個判斷,在遞歸一下clone函數就可以了

換用toSting()方法克隆:
思路:
  //1.遍歷對象              for(var prop in obj)
  //2.判斷要復制的屬性是否是原始值    typeof(obj[prop])
  //3.判斷要復制的屬性是數組還是對象   toString(建議使用)   instanceof   constructor
  //4.創建對應的數組和對象
 
instanceof:  a instanceof b  判斷對象a是否在構造函數b的原型鏈上
 
 
  function deepClone(origin, target) {
    var target = target || {};
    toStr = Object.prototype.toString, //對象調用toSting()
    arrStr = "[obect Array];"
    for(var prop in origin) {
    if(origin.hasOwnProperty(prop)) { //判斷是否是原型上的屬性還是自己的屬性
      if(origin[prop] !== "null" && typeof(origin[prop]) == "object") { //判斷是數組還是對象且復制者不能為空
        if(toStr.call(origin[prop]) == arrStr) {
          target[prop] = [];
        } else {
          target[prop] = {};
        }
          deepClone(origin[prop], target[prop]);
        } else {
          target[prop] = origin[prop];  //遞歸調用
        }
      }
    }
    return target;
  }

ps:值得注意的是,官方有一種方法可以生成新的函數實例,就是bind()

function aaa(){
    console.log(this);
};

var c = aaa;
var d = aaa.bind(); //bind如果不傳東西,默認是window對象

c === aaa; //true
d === aaa; //false

2.JSON對象序列化方法

這個方法明顯是簡單得多,但是有個弊端,就是不能復制函數

var obj = {a:1,b:2}  
var newObj = JSON.parse(JSON.stringify(obj)); 
obj.c = 3;
console.log(obj,newObj);

3.dom元素的復制——cloneNode

<div id="box"></div>
let div = document.getElementById('box'); let box2 = div.cloneNode(true);
console.log(div,box2);

4.es6新方法——Object.assign

//比較常用
var obj = {a:1,b:2} var newObj = Object.assign({}, obj);
obj.c = 3;
console.log(obj,newObj);

5.es6新方法——擴展運算符(...)

var obj = {a:1,b:2}  
var newObj ={...obj}
obj.c = 3;
console.log(obj,newObj);


免責聲明!

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



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