js物件拷貝的方法
阿新 • • 發佈:2019-01-09
物件拷貝的方法是一個難點,尤其是深拷貝。建議把程式碼都執行下,幫助理解拷貝。
一. json方法
1. 適合情況:
JSON物件的深度克隆。方法是先JSON.stringify() 轉為json字串, 再JSON.parse() 轉為json陣列
2. 缺點:
a. 如果你的物件裡有函式, 函式無法被拷貝下來
b. 無法拷貝copyObj物件原型鏈上的屬性和方法
var obj = { x: 1, y: { a: 1, b: 0, c: [1, 2, 3] } }; // 相同的引用 var obj2 = obj; console.log(obj2 == obj); //true 直接複製只是複製物件的指標,還指向同一個物件 //不同的引用 var obj3 = JSON.parse(JSON.stringify(obj)); console.log(obj3 == obj) //false 通過json方法複製後的地址不一樣 console.log(obj3);
二. jQuery extend方法
jQuery.extend(object)
概述:
擴充套件jQuery物件本身,用來在jQuery名稱空間上增加新函式。
var obj = {
x: 1,
y: {
a: 1,
b: 0,
c: [1, 2, 3]
}
};
var obj2 = $.extend({}, obj);
console.log(obj2 == obj) //false 複製後的地址不一樣
console.log(obj2);
三. Object.create()方法
複製物件存在於Object原型prototype中
var obj = {
x: 1,
y: {
a: 1,
b: 0,
c: [1, 2, 3]
}
};
var obj2 = Object.create(obj);
console.log(obj2 == obj); //false
console.log(obj2);
四. for迴圈遍歷方法
1. 淺拷貝:
只是拷貝了基本型別的資料;然而引用型別資料, 只是複製了指標,複製後也是會發生引用。
除了這個是淺拷貝,本文章介紹的其他方法都是深拷貝。
var obj = { x: 1, y: { a: 1, b: 0, c: [1, 2, 3] } }; var obj2 = {}; for (var i in obj) { //for in 會遍歷物件的屬性,包括例項中和原型中的屬性。(需要可訪問,可列舉屬性) obj2[i] = obj[i]; } console.log(obj2); obj2.y.c.push(4); //給新陣列新增一個元素4,會同步反映在新舊陣列中 console.log(obj2.y.c); // [1,2,3,4] console.log(obj.y.c); // [1,2,3,4] 淺拷貝只是複製了地址,修改是記憶體中的資料
2. 深拷貝
深拷貝, 就是遍歷那個被拷貝的物件。判斷物件裡每一項的資料型別。如果不是物件型別, 就直接賦值, 如果是物件型別, 就再次呼叫遞迴的方法去賦值。
var obj = {
x: 1,
y: {
a: 1,
b: 0,
c: [1, 2, 3]
}
};
function getClass(o) { //判斷資料型別
return Object.prototype.toString.call(o).slice(8, -1);
}
function deepCopy(obj) {
var result, oClass = getClass(obj);
if (oClass == "Object") result = {}; //判斷傳入的如果是物件,繼續遍歷
else if (oClass == "Array") result = []; //判斷傳入的如果是陣列,繼續遍歷
else return obj; //如果是基本資料型別就直接返回
for (var i in obj) {
var copy = obj[i];
if (getClass(copy) == "Object") result[i] = deepCopy(copy); //遞迴方法 ,如果物件繼續變數obj[i],下一級還是物件,就obj[i][i]
else if (getClass(copy) == "Array") result[i] = deepCopy(copy); //遞迴方法 ,如果物件繼續陣列obj[i],下一級還是陣列,就obj[i][i]
else result[i] = copy; //基本資料型別則賦值給屬性
}
return result;
}
var obj2 = deepCopy(obj);
console.log(obj2);
五. 原型鏈繼承方法
function Father() {
this.say = "hi";
this.fn = function () {
return this.say;
}
}
Father.prototype.eat = function () {
console.log('吃');
}
function Son() {
this.play = function () {
console.log('play game');
}
}
//通過原型來繼承父類的公共屬性
Son.prototype = new Father();
var s = new Son();
console.log(s);
console.log(s.say); //hi
console.log(s.fn()); //hi