Prototype原型模式详解(转)

el/2024/4/13 14:25:35

javascript开发人员对prototype这个东西恐怕都十分熟悉了,可是对于prototype模式了解的人恐怕不是很多。
原型模式的用意是:通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多的同类型对象。
和其他创建型模式不同:prototype模式创建对象不是通过new一个类,而是通过一个现有的对象实例来的。有经验的编程人员应该都接触过对象的clone方法,这就是原型模式的应用。
很多文章关于生活中原型模式的例子,用的是细胞的分裂来描述,是比较贴切的。
下面是一个比较实际的web应用中的例子,通过现有的dom元素对象,创建了一个新的副本。这个副本dom元素并没有使用document.createElement方法创建。

TestDiv


<script>
var testClone = document.getElementById('test').cloneNode(true);
document.body.appendChild(testClone);
</script>
原型模式通过拷贝对象成员来创建新的对象。这个过程分为两种情况:浅拷贝和深拷贝。
当对象执行了浅拷贝,新对象和原对象中,引用类型成员仍然指向同一个地址,修改操作可能相互影响。
当对象执行了深拷贝,新对象和原对象就没有任何共享的东西,任何一个对象的修改不会影响到另外一个对象。
浅拷贝示例:
function Writer (name, sex) {
    this.name = name;
    this.sex = sex;
}
function Book (name, pages, price, writer) {
    this.name = name;
    this.pages = pages;
    this.price = price;
    this.writer = writer;
}
Book.prototype.clone = function () {//深拷贝浅拷贝的区别就在这个function里
    return new Book(this.name,
                        this.pages,
                        this.price,
                        this.writer);
}
var writer = new Writer('谭振林', '男');
var bookName = '深入解析ASP.NET控件开发';
var myBook = new Book(bookName, 611, 70, writer);
var otherBook = myBook.clone();
myBook.name = '不是深入解析ASP.NET控件开发';    //值类型的修改不会相互影响
alert([myBook.name,otherBook.name]);//所以这里打印:不是深入解析ASP.NET控件开发,深入解析ASP.NET控件开发
myBook.writer.name = '不是谭震林';    //引用类型的修改会相互影响,因为他们引用同个内存地址
alert([myBook.writer.name, otherBook.writer.name]);//所以这里打印:不是谭震林,不是谭震林
深拷贝示例:
function Writer (name, sex) {
    this.name = name;
    this.sex = sex;
}
function Book (name, pages, price, writer) {
    this.name = name;
    this.pages = pages;
    this.price = price;
    this.writer = writer;
}
Book.prototype.clone = function () {//深拷贝浅拷贝的区别就在这个function里
    var writer = new Writer(this.writer.name,this.writer.sex);
    return new Book(this.name,
                        this.pages,
                        this.price,
                        writer);
}
var writer = new Writer('谭振林', '男');
var bookName = '深入解析ASP.NET控件开发';
var myBook = new Book(bookName, 611, 70, writer);
var otherBook = myBook.clone();
myBook.name = '不是深入解析ASP.NET控件开发';    //值类型的修改不会相互影响
alert([myBook.name,otherBook.name]);//所以这里打印:不是深入解析ASP.NET控件开发,深入解析ASP.NET控件开发
myBook.writer.name = '不是谭震林';    //深拷贝,引用已经指向不同内存地址,修改不会相互影响
alert([myBook.writer.name, otherBook.writer.name]);//所以这里打印:不是谭震林,谭震林
这里 顺带说明一下,javascript中的面向对象机制是通过prototype实现的,在new一个对象的时候,其实并没有为每一个对象创建每个prototype成员的副本,而是将对象成员指针指向prototype成员,下面程序可以验证这点:
function Test () {
}
Test.prototype.alert = function () {
    alert('test');
}
var test1 = new Test();
var test2 = new Test();
alert(test1.alert === test2.alert);
test1.constructor.prototype.alert = function () {alert('test1');}
test2.alert();
说的白一点,prototype模式就是用来(通过)复制(创建)对象的。那我们 什么时候应该使用prototype模式呢?我认为:
1.当你要创建的对象与现有运行时对象相似度很大时
2.为了避免创建类的工厂类导致层次复杂度增加时
3.当类的实例只有不多的几种状态时(此时需要引进原型管理器)
关于少量状态时引入 原型管理器引导对象的创建,实例如下:
StyleTest

<script>
//类定义
function StyleItem (fontSize, color) {
    this.fontSize = fontSize;
    this.color = color;
}
StyleItem.prototype.clone = function () {
    return {
        fontSize:this.fontSize,
        color:this.color
    }
}
//原型管理器
var StyleManager = {
    getStyle: function (key) {
        if (this[key]) {
            return this[key].clone();
        }
    }
};
//预创建类可能的状态集合对象
StyleManager['big'] = new StyleItem('16px', '#000');
StyleManager['normal'] = new StyleItem('14px', '#333');
StyleManager['small'] = new StyleItem('12px', '#666');
//无需再通过new来创建StyleItem类的对象了
var el = document.getElementById('styletest');
var style = StyleManager.getStyle('small');
for (var k in style)el.style[k] = style[k];
</script>


http://www.ngui.cc/el/4967340.html

相关文章

C/S 与B/S架构区别详解

一、什么是C/S和B/S 要想对“C/S”和“B/S”技术发展变化有所了解&#xff0c;首先必须搞清楚三个问题。 第一、什么是C/S结构。 C/S &#xff08;Client/Server&#xff09;结构&#xff0c;即大家熟知的客户机和服务器结构。它是软件系统体系结构&#xff0c;通过它可以充分利…

IBM面试常见问题

1.自我介绍(English) 自我评价 评价一下你自己是个怎样的人 2.性格素质 你的同学怎么看你 自己优点 那么你觉得你的缺点是什么&#xff1f; 你最遗憾的事情是什么&#xff1f; 你觉得你的性格怎么样&#xff1f; 3.大…

static和final关键字总结(转)

一、final 关键字final有“无法改变的”或者“终态的”含义&#xff0c;它可以修饰非抽象类、非抽象类成员方法和变量。 final类不能被继承&#xff0c;没有子类&#xff0c;final类中的方法默认是final的。 final方法不能被子类的方法覆盖&#xff0c;但可以被继承。 final成…

Linux全套完整视频教程

该系列视频涉及Linux学习的方方面面,入门的、高级的、编程的、安全的,都有了,每一套都很完整。 LinuxCBT Classic Edition 详情:http://club.topsage.com/thread-223331-1-1.html LinuxCBT Classic Edition 75小时全程演练Red Hat Linux 9,该视频全套分10个模块,从基础到…

linux任务管理器top的使用(转)

直接在终端输入top命令就行 第一行&#xff0c;很容易看出来了吧 简单说一下load average: * * * 第一个数是&#xff1a;平均&#xff15;分钟以内有多少进程在竞争&#xff23;&#xff30;&#xff35; 第二个数是&#xff1a;平均&#xff11;&#xff10;分钟以内有多少进…

centos5 设置静态IP

关于CENTOS更改自动获取IP为静态IP上网的方法 1.首先利用以下3个命令来查看自己机器的一些网络信息&#xff1a; ifconfig 可以查看网络设备及IP地址&#xff0c;子网掩码等信息 route 可以查看路由信息 DNS直接查看文件&#xff1a;[rootkcn-110mw]#c…

JVM的垃圾回收机制详解和调优(转)

1.JVM的gc概述 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存。java语言并不要求jvm有gc&#xff0c;也没有规定gc如何工作。不过常用的jvm都有gc&#xff0c;而且大多数gc都使用类似的算法管理内存和执行收集操作。 在充分理解了垃圾收集算法和执行过程后…

GRUB引导故障排除(转)

GRUB引导故障排除 在工作和教学中&#xff0c;经常发现同事和同学在碰到Linux启动直接进入GRUB界面但没有启动选单&#xff08;只剩下一个“grub>”提示符&#xff09;的状况&#xff0c;这时就认定系统已经没救&#xff0c;开始重新安装&#xff0c;甚至包括一些接触Linux…

Linux系统文件目录简介

一、简介: Linux操作系统中,以文件来表示所有的逻辑实体与非逻辑实体。逻辑实体系指文件与目录; 非逻辑实体则泛指硬盘、终端机、打印机等。 一般而言,Linux文件名称的组成除由连续字母、标点符号、数字等构成外,中间不能有空格符、路径名称符号 / 或 # * % & {} [] …….…

CentOS5.3下源码编译安装XEN3.4.2虚拟机

如果你对VMware很熟悉&#xff0c;那么你一定很想了解大名鼎鼎的XEN和KVM,XEN是20多年前由剑桥大学开发的&#xff0c;现在属于思杰公司&#xff08;Citrix),其目前最新版本是3.4.2&#xff0c;而KVM是新崛起的新星&#xff0c;是XEN不容忽视的强有力的竞争对手&#xff0c;呵呵…