javascript设计模式交流(二) Prototype Pattern(3)
作者:winter 来源:无忧脚本 发布时间:2007-11-29 14:01:00
完美的clone
为了实现完整的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 ret[p]!="object")ret[p]=this[p];
else ret[p]=deepClone.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的面向原型特性的实现方式。
PS.本文征求过月老大意见了 不是盗版滴 呵呵
后面补上UML图 gif版和visio版
visio版:prototype.rar (88.84 KB)


猜你喜欢
- 本文实例讲述了Python采用socket模拟TCP通讯的实现方法。分享给大家供大家参考。具体实现方法如下:对于TCP server端的创建
- 本篇文章主要内容代理类主要功能是将一个类实例的属性访问和控制代理到代码内部另外一个实例类,将想对外公布的属性的访问和控制权交给代理类来操作,
- MERGE 存储引擎把一组 MyISAM 数据表当做一个逻辑单元来对待,让我们可以同时对他们进行查询。构成一个 MERGE 数据表结构的各成
- 一、字符串离散化示例对于一组电影数据,我们希望统计电影分类情况,应该如何处理数据?(每一个电影都有很多个分类)思路:首先构造一个全为0的数组
- 一个小问题今天在做一个实验时,需要对一个包含中英文词汇的TXT文件进行读入和整理。Python代码的编码规则为UTF-8。在读入时,文件的每
- 使用tkFileDialog实现文件选择、保存和路径选择概述看了下Tkinter的文档,对于Pop-up dialog有三类,现在用到的是t
- var str = "pig cat fish、dog horse monkey bear、lion、fox&quo
- 进一法取整、四舍五入取整、忽略小数等的取整数方法大全PHP取整数函数常用的四种方法,下面收集了四个函数;经常用到取整的函数,今天小小的总结一
- Node.js Domain(域) 简化异步代码的异常处理,可以捕捉处理try catch无法捕捉的异常。Domain 模块可分为
- python代码 # -*- coding: utf-8 -*- import Image,ImageDraw,Imag
- 优化可能带来的问题优化不总是对一个单纯的环境进行,还很可能是一个复杂的已投产的系统。优化手段本来就有很大的风险,只不过你没能力意识到和预见到
- 具体代码如下所示:<!DOCTYPE html><html> <head> &
- python中关于删除list中的某个元素,一般有三种方法:remove、pop、del:1.remove: 删除单个元素,删除首个符合条件
- 外部引入<link href="https://cdn.bootcss.com/animate.css/3.5.2/anim
- 今天遇到一个问题,在同事随意的提示下,用了 itertools.groupby 这个函数。不过这个东西最终还是没用上。问题就是对一个list
- 例如我要测试一个创建网络的接口,需要先拿token值,而获取token的接口请求成功后,将token存在了响应头headers,postma
- MySQL 提供了一个很有意思的Engine:Federated!如果你了解Linux下面的Link的话,就应该很好理解这个Federate
- 先看一下合并后的样式,表格第二行,二三四列合并官网给我们提供了span-method的方法可以进行表格合并,有4个参数返回:row,colu
- 本文介绍了C#连接Oracle数据库的过程。通过instant client和ODP.net中的Oracle.DataAccess.dll,
- 本文实例为大家分享了python实现趣味图片字符化的具体代码,供大家参考,具体内容如下主要使用PIL库先放效果图:代码如下:#coding=