(function(){
var toString=Object.prototype.toString,gObj={},cloneHelper=function(cache,item){
/// <summary>helper for Utils.clone</summary>
if ('object' == typeof item || Utils.isFunction(item)) {
for (var i = cache.length - 2; i>=0; i -= 2) {
if (cache[i] == item)
return cache[i + 1]
}
cache.push(item, item = Utils.clone(item, cache))
}
return item
};
window.Utils={
isFunction:function(it){
/// <summary>判断参数是否为Function</summary>
/// <param name="it" type="Object">待判断的参数</param>
/// <returns type="Boolean" />
return toString.call(it)=='[object Function]';
},
clone:function(obj,cache){
/// <summary>克隆一个对象</summary>
/// <param name="o" type="Object">要克隆的目标对象</param>
/// <returns type="Object" />
cache || (cache = []);
var clone,temp;
if (!obj || (!Utils.isFunction(obj) && typeof obj != 'object')) return o;
else if (obj.cloneNode) return o.cloneNode(true);//克隆DOM节点,绑定事件的有问题,暂不处理
else if (Utils.isFunction(obj)) clone = new Function('return ' + obj)(); //克隆function eval在当前作用域,Funtion在全局
else clone = (temp = obj.constructor, clone = new temp(obj.valueOf()), obj == clone) ? new temp() : clone; //克隆其它对象,通过识别复制后的对象与原对象是否相同来决定传不传参数,像数组是不能传参数的
cache.push(obj,clone);
for (temp in obj) if (gObj.hasOwnProperty.call(obj,temp)) clone[temp] = cloneHelper(cache,obj[temp]);//使用gObj.hasOwnProperty 防止对象obj重写了hasOwnProperty方法
return clone
}
}());
支持节点克隆,对象克隆,同时也支持循环引用的对象克隆。
比如:
var souceObj={
childObj:{
}
};
sourceObj.childObj.child=sourceObj;
这样一个循环引用的对象也可以正常克隆
cloneObj=Utils.clone(sourceObj);克隆后,同样保持与原来相同的引用关系
对于
var obj={};
var a={};
a.b=obj;
a.c=obj;
var d=Utils.clone(a);
在clone之前
a.b.f='123';
那么a.c也就有了一个f 为 '123';
但对于 clone之后的d 也有这功能
然而,每段代码或解决方案都有它的适用范围,以上代码也无法保证在所有浏览器中对任意对象克隆均能正常工作,您应当看懂理解代码,学以至用,而不是简单的把代码复制过去
以上代码在opera某些版本下克隆正则有问题,已满足大部分需求
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。