网络编程
位置:首页>> 网络编程>> JavaScript>> javascript设计模式交流(二) Prototype Pattern(3)

javascript设计模式交流(二) Prototype Pattern(3)

作者:winter 来源:无忧脚本 发布时间:2007-11-29 14:01:00 

标签:Prototype,Pattern,模式,javascript

完美的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)

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com