**
1.淺拷貝
**
拷貝就是把父對像的屬性,全部拷貝給子對象。
下面這個函數,就是在做拷貝:
var Chinese = {
nation:'中國'
}
var Doctor = {
career:'醫生'
}
function extendCopy(p) {
var c = {};
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
return c;
}
使用的時候,這樣寫:
var Doctor = extendCopy(Chinese);
Doctor.career = '醫生';
alert(Doctor.nation); // 中國
但是,這樣的拷貝有一個問題。那就是,如果父對象的屬性等於數組或另一個對象,那麼實際上,子對象獲得的只是一個內存地址,而不是真正拷貝,因此存在父對象被篡改的可能。
請看,現在給Chinese添加一個”出生地”屬性,它的值是一個數組。
Chinese.birthPlaces = ['北京','上海','香港'];
通過extendCopy()函數,Doctor繼承了Chinese。
var Doctor = extendCopy(Chinese);
然後,我們爲Doctor的”出生地”添加一個城市:
Doctor.birthPlaces.push('廈門');
看一下輸入結果
alert(Doctor.birthPlaces); //北京, 上海, 香港, 廈門
alert(Chinese.birthPlaces); //北京, 上海, 香港, 廈門
結果是兩個的出生地都被改了。
所以,extendCopy() 只是拷貝了基本類型的數據,我們把這種拷貝叫做“淺拷貝”。
**
2.深拷貝
**
因爲淺深拷有如此弊端所以我們接下來看一下深拷貝
所謂”深拷貝”,就是能夠實現真正意義上的數組和對象的拷貝。它的實現並不難,只要遞歸調用”淺拷貝”就行了。
function deepCopy(p, c) {
var c = c || {};
for (var i in p) {
if (typeof p[i] === 'object') {
c[i] = (p[i].constructor === Array) ? [] : {};
deepCopy(p[i], c[i]);
} else {
c[i] = p[i];
}
}
return c;
}
看一下使用方法:
var Doctor = deepCopy(Chinese);
現在,給父對象加一個屬性,值爲數組。然後,在子對象上修改這個屬性:
Chinese.birthPlaces = ['北京','上海','香港'];
Doctor.birthPlaces.push('廈門');
alert(Doctor.birthPlaces); //北京, 上海, 香港, 廈門
alert(Chinese.birthPlaces); //北京, 上海, 香港
這樣就完成了拷貝;
$.extend()
jquery 中$.extend()如同。
$.extend( [deep ], target, object1 [, objectN ] )
•deep
類型: Boolean
如果是true,合併成爲遞歸(又叫做深拷貝)。
•target
類型: Object
對象擴展。這將接收新的屬性。
•object1
類型: Object
一個對象,它包含額外的屬性合併到第一個參數.
•objectN
類型: Object
包含額外的屬性合併到第一個參數
當我們提供兩個或多個對象給$.extend(),對象的所有屬性都添加到目標對象(target參數)。
請記住,目標對象(第一個參數)將被修改,並且將通過$.extend()返回。然而,如果我們想保留原對象,我們可以通過傳遞一個空對象作爲目標對象:
var object = $.extend({}, object1, object2);
在默認情況下,通過$.extend()合併操作不是遞歸的;如果第一個對象的屬性本身是一個對象或數組,那麼它將完全用第二個對象相同的key重寫一個屬性。這些值不會被合併。可以通過檢查下面例子中 banana 的值,就可以瞭解這一點。然而,如果將 true 作爲該函數的第一個參數,那麼會在對象上進行遞歸的合併。
警告:不支持第一個參數傳遞 false 。
1. 合併兩個對象,並修改第一個對象。
var object1 = {
apple: 0,
banana: { weight: 52, price: 100 },
cherry: 97
};
var object2 = {
banana: { price: 200 },
durian: 100
};
// Merge object2 into object1
$.extend( object1, object2 );
// Assuming JSON.stringify - not available in IE<8
console.log( JSON.stringify( object1 ) );
//{"apple":0,"banana":{"price":200},"cherry":97,"durian":100}
- 採用遞歸方式合併兩個對象,並修改第一個對象。
var object1 = {
apple: 0,
banana: { weight: 52, price: 100 },
cherry: 97
};
var object2 = {
banana: { price: 200 },
durian: 100
};
// Merge object2 into object1, recursively
$.extend( true, object1, object2 );
// Assuming JSON.stringify - not available in IE<8
console.log( JSON.stringify( object1 ) );
//{"apple":0,"banana":{"weight":52,"price":200},"cherry":97,"durian":100}
- 合併 defaults 和 options 對象,並且不修改 defaults 對象。這是常用的插件開發模式。
var defaults = { validate: false, limit: 5, name: "foo" };
var options = { validate: true, name: "bar" };
// Merge defaults and options, without modifying defaults
var settings = $.extend( {}, defaults, options );
console.log(JSON.stringify( defaults ));
console.log(JSON.stringify( options ));
console.log(JSON.stringify( settings ));
//defaults -- {"validate":false,"limit":5,"name":"foo"}
//options -- {"validate":true,"name":"bar"}
//settings -- {"validate":true,"limit":5,"name":"bar"}
Javascript 判斷對象是否相等
在Javascript中相等運算包括”==”,”===”全等,兩者不同之處,不必多數,本篇文章我們將來講述如何判斷兩個對象是否相等? 你可能會認爲,如果兩個對象有相同的屬性,以及它們的屬性有相同的值,那麼這兩個對象就相等。那麼下面我們通過一個實例來論證下:
var obj1 = {
name: "Benjamin",
sex : "male"
}
var obj2 = {
name: "Benjamin",
sex : "male"
}
//Outputs: false
console.log(obj1 == obj2);
//Outputs: false
console.log(obj1 === obj2);
通過上面的例子可以看到,無論使用”==”還是”===”,都返回false。主要原因是基本類型string,number通過值來比較,而對象(Date,Array)及普通對象通過指針指向的內存中的地址來做比較。看下面一個例子:
var obj1 = {
name: "Benjamin",
sex : "male"
};
var obj2 = {
name: "Benjamin",
sex : "male"
};
var obj3 = obj1;
//Outputs: true
console.log(obj1 == obj3);
//Outputs: true
console.log(obj1 === obj3);
//Outputs: false
console.log(obj2 == obj3);
//Outputs: false
console.log(obj2 === obj3);
上例返回true,是因爲obj1和ob3的指針指向了內存中的同一個地址。和麪向對象的語言(Java/C++)中值傳遞和引用傳遞的概念相似。 因爲,如果你想判斷兩個對象是否相等,你必須清晰,你是想判斷兩個對象的屬性是否相同,還是屬性對應的值是否相同,還是怎樣?
function person(name) {
this.name=name;
}
var p1 = new person("p1");
var p2 = new person("p2");
console.log(p1 == p2); //false
person.prototype.sayHi = function() {
// do sayHi here
}
console.log(p1.sayHi() == p2.sayHi()); //true
console.log(p1.sayHi() === p2.sayHi()); //true