有效的對(duì)象拷貝應(yīng)該是指深拷貝。
淺拷貝 : 就是兩個(gè)js 對(duì)象指向同一塊內(nèi)存地址,所以當(dāng)obj1 ,obj2指向obj3的時(shí)候,一旦其中一個(gè)改變,其他的便會(huì)改變!
深拷貝:就是重新復(fù)制一塊內(nèi)存,這樣就不會(huì)互相影響。
有些時(shí)候我們定義一個(gè)數(shù)組,把這個(gè)數(shù)據(jù)賦值給跟多對(duì)象數(shù)組中的一個(gè)字段,當(dāng)我們改變對(duì)象數(shù)組中的該字段的時(shí)候,我們會(huì)把原來的數(shù)組也改變了,這樣就會(huì)引起其他數(shù)組對(duì)象中的對(duì)應(yīng)的字段改變,這不是我們想要的。
這個(gè)時(shí)候我們會(huì)用到深拷貝。
深拷貝的方法:
var deepCopy = function(source)
{
var result;
(source instanceof Array) ? (result = []) : (result = {});
for (var key in source) {
result[key] = (typeof source[key]==='object') ? deepCopy(source[key]) : source[key];
}
return result;
}
||Object.prototype.clone = function() {
// Handle null or undefined or function
if (null == this || "object" != typeof this)
return this;
// Handle the 3 simple types, Number and String and Boolean
if(this instanceof Number || this instanceof String || this instanceof Boolean)
return this.valueOf();
// Handle Date
if (this instanceof Date) {
var copy = new Date();
copy.setTime(this.getTime());
return copy;
}
// Handle Array or Object
if (this instanceof Object || this instanceof Array) {
var copy = (this instanceof Array)?[]:{};
for (var attr in this) {
if (this.hasOwnProperty(attr))
copy[attr] = this[attr]?this[attr].clone():this[attr];
}
return copy;
}
throw new Error("Unable to clone obj! Its type isn't supported.");
}
function a() {
alert("aaaaa");
}
var b = a.clone();
b();
alert(b === a);
||Object.prototype.clone = function() { // Handle null or undefined or function if (null == this || "object" != typeof this) return this; // Handle the 3 simple types, Number and String and Boolean if(this instanceof Number || this instanceof String || this instanceof Boolean) return this.valueOf(); // Handle Date if (this instanceof Date) { var copy = new Date(); copy.setTime(this.getTime()); return copy; } // Handle Array or Object if (this instanceof Object || this instanceof Array) { var copy = (this instanceof Array)?[]:{}; for (var attr in this) { if (this.hasOwnProperty(attr)) copy[attr] = this[attr]?this[attr].clone():this[attr]; } return copy; } throw new Error("Unable to clone obj! Its type isn't supported.");}function a() { alert("aaaaa");}var b = a.clone();b();alert(b === a);。
要實(shí)現(xiàn)深復(fù)制有很多辦法,比如最簡(jiǎn)單的辦法有:var cloneObj = JSON.parse(JSON.stringify(obj)); 上面這種方法好處是非常簡(jiǎn)單易用,但是壞處也顯而易見,這會(huì)拋棄對(duì)象的constructor,也就是深復(fù)制之后,無論這個(gè)對(duì)象原本的構(gòu)造函數(shù)是什么,在深復(fù)制之后都會(huì)變成Object。
另外諸如RegExp對(duì)象是無法通過這種方式深復(fù)制的。所以這里我將介紹一種,我自認(rèn)為很優(yōu)美的深復(fù)制方法,當(dāng)然可能也存在問題。
如果你發(fā)現(xiàn)了我的實(shí)現(xiàn)方法有什么問題,請(qǐng)及時(shí)讓我知道~ 先決條件:1. 對(duì)于任何對(duì)象,它可能的類型有Boolean, Number, Date, String, RegExp, Array 以及 Object(所有自定義的對(duì)象全都繼承于Object)2. 我們必須保留對(duì)象的構(gòu)造函數(shù)信息(從而使新對(duì)象可以使用定義在prototype上的函數(shù)) 最重要的一個(gè)函數(shù):Object.prototype.clone = function () { var Constructor = this.constructor; var obj = new Constructor(); for (var attr in this) { if (this.hasOwnProperty(attr)) { if (typeof(this[attr]) !== "function") { if (this[attr] === null) { obj[attr] = null; } else { obj[attr] = this[attr].clone(); } } } } return obj; }; 定義在Object.prototype上的clone()函數(shù)是整個(gè)方法的核心,對(duì)于任意一個(gè)非js預(yù)定義的對(duì)象,都會(huì)調(diào)用這個(gè)函數(shù)。而對(duì)于所有js預(yù)定義的對(duì)象,如Number,Array等,我們就要實(shí)現(xiàn)一個(gè)輔助clone()函數(shù)來實(shí)現(xiàn)完整的克隆過程:/* Method of Array*/ Array.prototype.clone = function () { var thisArr = this.valueOf(); var newArr = []; for (var i=0; i<thisArr.length; i++) { newArr.push(thisArr[i].clone()); } return newArr; };/* Method of Boolean, Number, String*/ Boolean.prototype.clone = function() { return this.valueOf(); }; Number.prototype.clone = function() { return this.valueOf(); }; String.prototype.clone = function() { return this.valueOf(); };/* Method of Date*/ Date.prototype.clone = function() { return new Date(this.valueOf()); };/* Method of RegExp*/ RegExp.prototype.clone = function() { var pattern = this.valueOf(); var flags = ''; flags += pattern.global ? 'g' : ''; flags += pattern.ignoreCase ? 'i' : ''; flags += pattern.multiline ? 'm' : ''; return new RegExp(pattern.source, flags); }; 可能直接定義在預(yù)定義對(duì)象的方法上,讓人感覺會(huì)有些問題。
但在我看來這是一種優(yōu)美的實(shí)現(xiàn)方式。同時(shí)我也在開發(fā)一個(gè)插件,主要的思想也就是擴(kuò)展預(yù)定義對(duì)象的方法。
這個(gè)插件叫JustJS(Github項(xiàng)目地址) 有以下一些特性:1. 同時(shí)支持Web前端和node.js使用。2. 直接對(duì)預(yù)定義對(duì)象的方法進(jìn)行擴(kuò)展3. 使用 J(function(){。
}) 語句塊,決不污染全局命名空間。目前只寫了一小部分,同時(shí)也寫了些簡(jiǎn)單的文檔,有興趣的同學(xué)可以看一下,也可以加入我,F(xiàn)ork我的項(xiàng)目,喜歡的同學(xué)還可以給Star!。
這題的意思是把一個(gè)對(duì)象中的內(nèi)容一級(jí)一級(jí)的復(fù)制到另外一個(gè)對(duì)象中。用for(var i in obj)的方式就可以了。
至于類型,js雖然是弱類型,但其實(shí)是有類型的,如數(shù)字類型,就是Number,對(duì)象類型就是Object,String,Date,Array,Boolean,Function等,然要判斷對(duì)象的類型也很簡(jiǎn)單,如:
var a = 2;
a.constructor == Number;// 判斷是否為數(shù)值
a.constructor == String;// 判斷是否為字符串 a = "test"
a.constructor == Date;// 判斷是否為日期 a = new Date()
a.constructor == Array;// 判斷是否為數(shù)組 a = [1,"2",true]
a.constructor == Boolean;// 判斷是否為布爾型 a = true
a.constructor == Object;// 判斷是否為對(duì)象 a = {}
a.constructor == Function;// 判斷是否為方法類型 a = function(){}
拷貝可以使用:對(duì)象.createTextRange().execCommand("copy")命令,你可以用:window.clipboardData.setData("text",內(nèi)容的來源)這里內(nèi)容的來源例如要取得文本框ID為y里的文本復(fù)制到剪切板,這里寫y.value粘貼其實(shí)就是目標(biāo)對(duì)象的value屬性=y.value剪切是以選擇為基礎(chǔ)的,先必須建立選擇區(qū)域,如有個(gè)文本框ID為a,要剪切里面的文本需要:a.createTextRange().execCommand("cut")來完成剪切。
全選,如有個(gè)文本框ID為b,則全選的話只需b.select()即可。
JavaScript中要實(shí)現(xiàn)繼承,其實(shí)就是實(shí)現(xiàn)三層含義:1、子類的實(shí)例可以共享父類的方法;2、子類可以覆蓋父類的方法或者擴(kuò)展新的方法;3、子類和父類都是子類實(shí)例的“類型”。
JavaScript中,并不直接從語法上支持繼承,但是可以通過模擬的方法來實(shí)現(xiàn)繼承,以下是關(guān)于實(shí)現(xiàn)繼承的幾種方法的總結(jié):1、構(gòu)造繼承法2、原型繼承法3、實(shí)例繼承法4、拷貝繼承法1、構(gòu)造繼承法:在子類中執(zhí)行父類的構(gòu)造函數(shù)。 12、原型繼承法:JavaScript是一種基于原型的語言。
要了解什么是“原型繼承法”,先了解一下prototype的特性:prototype的最大特性是能夠讓對(duì)象實(shí)例共享原型對(duì)象的屬性,因此如果把某個(gè)對(duì)象作為一個(gè)類型的原型,那么我們說這個(gè)類型的所有實(shí)例都一這個(gè)對(duì)象為原型。這個(gè)時(shí)候,實(shí)際上這個(gè)對(duì)象的類型也可以作為那些以這個(gè)對(duì)象為原型的實(shí)例的類型。
假如:Point類的對(duì)象作為Point2D類型的原型(Point2D.prototype = new Point(2)),那么說Point2D的所有實(shí)例都是以Point類的對(duì)象為原型。此時(shí),實(shí)際上Point類就可以作為Point2D類型的對(duì)象的類型(相當(dāng)于Point2D類型“繼承”了Point類型)。
見例:1 <script LANGUAGE="JavaScript"> 2 方法,可以被繼承14 {15 return this.dimension*2;16 }1718 function Point2D(x,y) //定義一個(gè)Point2D類19 {20 this.x = x;21 this.y = y;22 }2324 Point2D.prototype = new Point(2); //運(yùn)行“原型繼承法”使Point2D繼承Point2526 function Point3D(x,y,z) //定義Point3D類27 {28 this.x = x;29 this.y = y;30 this.z = z;31 }3233 Point3D.prototype = new Point(3); //Point3D繼承Point類3435 var p2 = new Point2D(1,2); //構(gòu)造一個(gè)Point2D對(duì)象3637 var p3 = new Point3D(1,2,3); //構(gòu)造一個(gè)Point3D對(duì)象3839 dwn(p2.dimension); //240 dwn(p3.dimension); //341 dwn(p2.distance()); //4 可以繼承靜態(tài)方法42 dwn(p3.distance()); //6 可以繼承靜態(tài)方法<。
可以利用JS中的for in語法進(jìn)行處理,具體如下:
//要復(fù)制的原對(duì)象
var destobj={ colkey: "col", colsinfo: "NameList" }
//復(fù)制的目標(biāo)對(duì)象
var myobj=new Object();
for(var om in myobj)
{
var name=om;//屬性名稱
var value=destobj[om];//屬性對(duì)應(yīng)的值
myobj[name]=destobj[om];
}
如果是使用了 JQ EXTJS 的話本身就有 對(duì)象克隆的 函數(shù)庫可以使用 如 extjs 使用
ext.ux.util.clone()
沒有用這些的話 可以自己寫一個(gè) 克隆函數(shù) 網(wǎng)上有資源 比如
function deepClone(obj){ var result={},oClass=isClass(obj);
// if(oClass==="Object"){
// result={};
// }else if(oClass==="Array"){
// result=[];
// }else{
// return obj;
// }
for(key in obj){
var copy=obj[key];
if(isClass(copy)=="Object"){
result[key]=arguments.callee(copy);
}else if(isClass(copy)=="Array"){
result[key]=arguments.callee(copy);
}else{
result[key]=obj[key];
}
}
return result;
}
function isClass(o){
if(o===null) return "Null";
if(o===undefined) return "Undefined";
return Object.prototype.toString.call(o).slice(8,-1);
}或者參考 extjs 的方法
function(o) {
if(!o || 'object' !== typeof o) { return o; }
if('function' === typeof o.clone) { return o.clone(); }
var c = '[object array]' === object.prototype.tostring.call(o) ? [] : {};
var p, v;
for(p in o) {
if(o.hasownproperty(p)) { v = o[p];
if(v && 'object' === typeof v) {
c[p] = ext.ux.util.clone(v);
} else {
c[p] = v;
}
}
}
return c;};
聲明:本網(wǎng)站尊重并保護(hù)知識(shí)產(chǎn)權(quán),根據(jù)《信息網(wǎng)絡(luò)傳播權(quán)保護(hù)條例》,如果我們轉(zhuǎn)載的作品侵犯了您的權(quán)利,請(qǐng)?jiān)谝粋€(gè)月內(nèi)通知我們,我們會(huì)及時(shí)刪除。
蜀ICP備2020033479號(hào)-4 Copyright ? 2016 學(xué)習(xí)鳥. 頁面生成時(shí)間:4.046秒