`
caniggia1986
  • 浏览: 151494 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

javascript clone

阅读更多
<a href="http://bbs.51js.com/forum.php?mod=viewthread&tid=74167&extra=pageD1%3D&page=1">ref</a>
<pre>
1.基本类型string boolean undefined null number皆可直接用=赋值
2.普通object clone
//最简单clone
function objectClone(){
	var ret=new Object();
	for(var p in this){
		ret[p]=this[p];
	}
	return ret;
}
//deep clone
function objectDeepClone(){
	var ret=new Object();
	for(var p in this){
		if(typeof this[p]!=object){
			ret[p]=this[p];
		}else{ 
			ret[p]=objectDeepClone.call(this[p]);
		}
	}
	return ret;
}
//利用构造器prototype属性赋值进行clone
function objectPrototypeClone(){
	var tmp=function(){};
	tmp.prototype=this;
	return new tmp;
}

这样clone出来的对象只读地共享一个原型的属性,它的最大优势是速度非常快,当我们希望快速复制大型对象时,可以使用这种方式,<blockquote>但是它会造成访问速度降低,而且它实时反映父节点的变化。</blockquote>
3.内置对象的clone
3.1Function
对Function来说,完全产生一个副本是不可能的,因为我们无法保证构造的函数跟原来的函数在同一作用域,但是不包含作用域的实现是很容易的:eval(this);或者使用Function构造 return Function(new String("return ")+this)();
Function本身是个Object 因此必须加上Object的clone 实现functionPrototypeClone需要一点小花招
function functionDeepClone(){
	var ret=Function(new String("return ")+this)();
	for(var p in this){
		if(typeof this[p]!=object){
			ret[p]=this[p];
		}else{
			ret[p]=objectDeepClone.call(this[p]);
		}
	}
	return ret;
}
//原型clone
function functionPrototypeClone(){                
	var tmp=Function.prototype;//备份
	Function.prototype=this;//改变原型
	var ret=(new Function(new String("return ")+this))();
	Function.prototype=tmp;//恢复原型
	return ret;
}

3.2Array
function arrayDeepClone(){
	var ret=new Array();
        //用for in考虑var a = [1,2,3];a["x"] = 100;这种情况 arrObj.slice(0)就有问题
	for(var p in this){
		if(typeof this[p]!=object){
			ret[p]=this[p];
		}else{
			ret[p]=objectDeepClone.call(this[p]);
		}
	}
	return ret;
} 
function arrayPrototypeClone(){                
	var tmp=Array.prototype;
	Array.prototype=this;
	var ret=new Array();
	Array.prototype=tmp;
	return ret;
}
//其他的一些实现arrayClone的方法,如:
function(){
    return Array.apply([],this);
}

function(){
    return [].concat(this);
}

3.3Date
function dateDeepClone(){
	var ret=new Date();
	ret.setTime(this.getTime());
	for(var p in this){
		if(typeof this[p]!=object){
			ret[p]=this[p];
		}else{
			ret[p]=objectDeepClone.call(this[p]);
		}
	}
	return ret;
} 
function datePrototypeClone(){                
	var tmp=Date.prototype;
	Date.prototype=this;
	var ret=new Date();
	ret.setTime(this.getTime());
	Date.prototype=tmp;
	return ret;
}

3.4String Boolean Number都是只读的对象,所以只要=就可以了
3.5完整的clone

function clone(){
	var ret;
	if(this instanceof Function){
		ret=Function(new String("return ")+this)();
	}else if(this instanceof Array){
		ret=new Array();
	}else if(this instanceof Date){
		ret=new Date();
		ret.setTime(this.getTime());
	}else if( (this instanceof String) || (this instanceof Boolean) || (this instanceof Number) ){
		return this;
	}else{
		ret=new Object();
	}
	
	for(var p in this){
		ret[p]=this[p];
	}
	
	return ret;
}

function deepClone()
{
	var ret;
	if(this instanceof Function){
		ret=Function(new String("return ")+this)();
	}else if(this instanceof Array){
		ret=new Array();
	}else if(this instanceof Date){
		ret=new Date();
		ret.setTime(this.getTime());
	}else if( (this instanceof String) || (this instanceof Boolean) || (this instanceof Number) ){
		return this;
	}else{
		ret=new Object();
	}

	for(var p in this){
		if(typeof this[p]!=object){
			ret[p]=this[p];
		}else{
			ret[p]=objectDeepClone.call(this[p]);
		}
	}
	return ret;
}
function prototypeClone(){
	if(this instanceof Function){
		var tmp=Function.prototype;
		Function.prototype=this;
		var ret=(new Function(new String("return ")+this))();
		Function.prototype=tmp;
		return ret;
	}else if(this instanceof Array){
		var tmp=Array.prototype;
		Array.prototype=this;
		var ret=new Array();
		Array.prototype=tmp;
		return ret;
	}else if(this instanceof Date){
		var tmp=Date.prototype;
		Date.prototype=this;
		var ret=new Date();
		ret.setTime(this.getTime());
		Date.prototype=tmp;
		return ret;
	}else if( (this instanceof String) || (this instanceof Boolean) || (this instanceof Number) ){
		return this;
	}else{
		var constructor=function(){};
		constructor.prototype=this;
		return new constructor;
	}
}

   前面讨论了三种Clone的实现方法,它们各自具有适合的语义环境,比如对一个数组来说 若是把它理解为一个集合Collection 则应该使用浅clone(假如集合A是B的子集,则应保证A.clone()亦是B的子集),若是把它理解为一个向量Vector,则应使用深clone(保证对向量A的分量操作不应影响向量A.clone()的分量)。prototypeClone的一个最常见的应用场景是深度优先搜索算法算法,为了扩展解空间树,我们通常需要快速的构造一个副本,如果使用clone或者deepClone 这将非常慢,而深度优先搜索的特点是在字节点被销毁之前,父节点不会变化,所以prototypeClone是非常合适的。

附:Prototype-oriented Programming和Prototype Pattern
面向原型的语言思想跟原型模式是完全一致的:从同一原型clone出来的对象就是一类对象。Prototype-oriented的语言对这种模式提供了语言级别的支持,即所有"类"的定义都是通过指定该类的一个原型来实现的(Class-Based Programming是通过类结构声明来描述一类对象,meta-class则是通过构造一个"类对象"来描述一类对象)。每次实例话就clone一次原型,然而这种方式会造成信息的冗余:所有对象都持有原型对象的一个clone的副本,而且一旦某一对象被构造,修改原型不会对它造成任何影响,这对于希望在程序中统一改变某一类对象的人来说很不方便。于是,一种变通的方法产生了:引用型原型对象,与之相对,原来的原型对象使用方法被称为 复制型原型对象。引用型原型对象不再clone原型,而是保存一个指向原型的指针,当访问属性时,首先检查自己的属性,当查到不存在时,则通过指针向原型索取相应属性。而引用型原型就是javascript的面向原型特性的实现方式。
</pre>
分享到:
评论

相关推荐

    深化理解JavaScript中的对象复制(Object Clone)_.docx

    在JavaScript中,对象复制,也称为克隆,是一项关键的编程技巧,用于创建一个对象的新副本,而不会改变原始对象。JavaScript的浅复制和深复制是两个重要的概念,它们在处理复杂数据结构时尤为关键。 浅复制...

    深入理解JavaScript中的对象复制(Object Clone)

    在深入探讨JavaScript中的对象复制(Object Clone)时,首先需要明确JavaScript中的对象复制分为浅复制(Shallow Copy)和深复制(Deep Copy)。浅复制指的是创建一个新对象,这个对象有着原始对象属性值的一份精确...

    Javascript对象Clone实例分析

    本文实例讲述了Javascript对象Clone用法。分享给大家供大家参考。具体如下: Object.prototype.Clone=function() { var objClone=new this.constructor(); //这里是创建一个与被Clone对象相同结构的对象 for(var...

    javascript中clone对象详解

     JavaScript中,简单的方法就是用JSON函数,将对象stringify成字符串,再parse成一个新对象。要么就是从网上搜个代码,开源社区里面clone的代码还是有不少的。  代码虽然可以找得到,但,东西永远是别人的,动手学...

    ThreeNodes.js, 在 javascript/中,vvvv"clone".zip

    ThreeNodes.js, 在 javascript/中,vvvv"clone" ThreeNodes.js 实验这是一个在 javascript 。html和中制作像"vvvv"这样的东西的实验。现场演示:http://idflood.github.com/ThreeNodes.js/关键原则模

    前端开源库-better-clone

    5. **兼容性**: `better-clone` 针对不同的 JavaScript 环境进行了优化,包括浏览器环境和 Node.js 环境,使得它在各种平台上都能稳定工作。 6. **API 简洁易用**: `better-clone` 提供了一个简单的 API,即 `...

    flow-clone-源码.rar

    "flow-clone"可能是一个用于数据流复制或者对象克隆的库,它在处理复杂数据结构时,尤其是在处理JavaScript中的引用类型时,可能有着独特的优化策略。 首先,我们需要了解"flow"通常在编程中指的是数据的流动方向或...

    前端开源库-lutils-clone

    `lutils-clone`是一个专门用于JavaScript对象克隆的开源库,它提供了一个高效、可靠且递归的解决方案,确保深拷贝过程中原始对象与克隆对象之间不会相互影响。 JavaScript的内置`Object.assign()`方法可以实现浅...

    vJavascript-clone:香草Javascript研究

    在"vJavascript-clone"项目中,我们可以推测其主要研究了如何使用JavaScript来实现对象的深度克隆。在JavaScript中,对象是引用类型,当进行赋值操作时,实际上是复制了对象的引用而不是对象本身。这可能导致意外的...

    Javascript-Noita-Clone:javascript的元胞自动机

    Javascript-Noita-Clone javascript的Cellular Automata。向下滚动页面以查看您可以放置​​的所有元素。如果您想添加新元素,请转到data.js,然后将其添加到元素中,这样您将看到它。在以下位置给我: 或如果您想...

    javascript数据值复制函数

    实现一个函数clone,可以对JavaScript中的5种主要的数据类型(包括Number、String、Object、Array、Boolean)进行值复制。

    pop-clone:用于克隆 JavaScript 对象图的多态运算符

    这个 JavaScript 包导出一个深度克隆运算符,它接受可能包含引用循环的任意对象图。 clone 操作符委托给实现它的任何对象的 clone 方法。 $ npm install --save pop-clone clone 方法接受一个值或对象图,并返回一...

    2048-clone-js:2048 的 JavaScript 克隆

    "2048-clone-js"项目就是一个基于JavaScript语言的2048游戏克隆版,由黛比·米尔本和卢西安·卡恩两位开发者共同完成。这个游戏的实现不仅展示了JavaScript的基础语法和面向对象编程思想,还涉及到DOM操作、事件监听...

    threes-js-clone:Threes 的 Javascript 克隆

    《Threes-js-Clone:JavaScript实现的Threes游戏克隆》 Threes!是一款备受欢迎的数字合并益智游戏,其简洁的设计和富有挑战性的玩法吸引了众多玩家。在这个项目中,我们将探讨一个名为"threes-js-clone"的...

    javascript-snake-clone-from-scratch:我做过学习javascript的项目

    javascript-snake-clone-from-scratch 我做过学习javascript的项目 我是从零开始做这个项目的,而没有研究任何关于游戏如何运作的教程,并且认为将它盲目地创建出来,而只是查找我想做什么的语法是最有效的学习方法...

    gitclone.com:gitclone.com网站

    同时,HTML还可以与CSS(层叠样式表)和JavaScript结合使用,实现网页的美化和交互效果。 为了实现动态功能,如用户登录、项目创建和克隆等,GitClone.com会使用服务器端的技术,如PHP、Python、Ruby或Node.js等,...

    trello-board-clone-front-end:使用JavaScript Web组件的Trello板克隆前端(仍在进行中)

    trello-board-clone 使用JavaScript Web组件的Trello板克隆用法要运行一个示例,请执行以下操作: 安装进行假API调用所需的 转到db.json所在的data目录,然后运行json-server --watch db.json 服务器运行后,只需...

    curso-javascript-projeto-calculadora-clone

    【标题】:“curso-javascript-projeto-calculadora-clone” 指的可能是一个JavaScript课程项目,目标是创建一个计算器的克隆版。在这个项目中,学生将学习如何运用JavaScript语言来实现一个功能齐全的计算器应用,...

    emacs, 已经准备好使用Emacs设置进行JavaScript和.zip

    emacs, 已经准备好使用Emacs设置进行JavaScript和 azer安装的EmacsReady-to-use Emacs的JavaScript设置和编程。 安装$ cd ~$ git clone https://github.com/azer/emacs$ cd ema

Global site tag (gtag.js) - Google Analytics