Javascript 构造函数模式、原型模式

前两天写完组合继承,打算总结一下原型继承的,不过今天看了一下工厂模式、构造函数模式和原型模式,觉得有必要总结一下以加深印象。

——————————————————————————————————————————————————————————————————————————————————碎碎念。

1.工厂模式

《Javascript 高级程序设计(第3版)》 用了寥寥十多行介绍了工厂模式。我找了一些相关资料,想确定一下这种模式的具体适用场景和优势。按照资料中的说法,是考虑到 ECMAScript 无法创建类,所以:

创建一个对象,紧接着描述对象的属性和方法,最后用另一个对象把它们封装起来当作接口。

按照上面描述的,工厂函数是用来在 Javascript 中实现类似于 Java 中类的功能。通过调用工厂函数,可以创建多个相似的对象实例。

    简单工厂模式:使用一个类(通常为单体)来生成实例。
    复杂工厂模式:使用子类来决定一个成员变量应该是哪个具体的类的实例。

关于 Javascript 使用工厂模式的优点,根据网上的总结,大概有以下几点:

a. 消除对象之间的耦合(这个不太明白,消除谁与谁的耦合?);

b. 在进行批次相关设置时,把所有实例化的代码都集中在一个位置,有助于创建模块化的代码,减少代码量;

c.  用于许多小型对象组成一个大对象。

缺点:

a. 没有解决对象识别的问题。

 

.....这个模式先留着吧,没太搞透彻优势在哪。以后领悟了的话再来补充。引用《Javascript 设计模式与开发实践》P5中的一段话:

“而在 Javascript 这种类型模糊的语言中,对象多态性是天生的,一个变量既可以指向一个类,又可以随时指向另外一个类。Javascript 不存在类型耦合问题,自然也没有必要刻意把对象“延迟”到子类创建,也就是说,Javascript 实际上是不需要工厂方法模式的。 模式的存在首先是能为我们解决什么问题,这种牵强的模拟只会让人觉得设计模式既难懂又没什么用。”

2. 构造函数模式

关于封装: 在 Javascript 中,可以将一些属性和方法封装到构造函数内;

关于多态:在 Javascript 中不存在重载的概念,但可以通过参数个数和类型判断来模拟重载,但是 Javascript 中多态是与生俱来的。一个最简单的栗子:

同一个构造函数实例化得到的两个对象实例,可以给它们传入不同的参数,这两个对象实例是不同的。这就是面向对象编程的多态。

利用构造函数模式,可以创建多个实例,这些实例都被标定为了特定的类型。构造函数模式相比于工厂模式更为简单且易于实现,但也存在缺点:

function Person(name,age,job){this.name = name;this.age = age;this.job = job;this.arr = [];this.sayName = function(){alert(this.name);};
}
var person1 = new Person("Nicholas",29,"Software Engineer");
var person2 = new Person("Greg",27,"Doctor");console.log(person1.sayName==person2.sayName);//false
person1.arr.push(1);
console.log(person1.arr);//1

person2.arr.push(2);
console.log(person2.arr);//2

利用构造函数每实例化一个实例对象,构造函数内的方法都要在实例上重新创建一次。通过 person1.sayName==person2.sayName 返回的返回结果可以看到两个实例引用的方法是不同的。

注意:这一点也适用于数组。

可以通过将构造函数的方法放在外部,使得对象实例每次都引用同一个方法。

function Person(name,age,job){this.name = name;this.age = age;this.job = job;this.sayName = sayName;
}function sayName(){alert(this.name);
}var person1 = new Person("Nicholas",29,"Software Engineer");
var person2 = new Person("Greg",27,"Doctor");console.log(person1.sayName==person2.sayName);//true

通过将构造函数的方法提到外部作为:特权方法。可以使实例获得相同的方法引用。

但是这种方法也存在一些问题:将方法提到外部作为特权方法使得封装性变差。如果构造函数内部有很多个方法,这样做后果更为明显。

另外再看一个问题:如果构造函数内有多个固定属性,并且存在多个方法。实例化的时候要为每个对象都复制相同的固定属性,如果将方法放在构造函数内部,这些方法也要复制,即使都作为特权函数,也存在弊端。

总结,构造函数模式存在两点不足:1. 浪费内存;2. 可能会使封装性变差。

3.原型模式

原型模式的出现,解决了构造函数实例化过程中对固定属性个方法重复深复制的问题。

对于相同的属性和方法,只要在构造函数的原型对象上申明一次,构造函数的实例就可以共享同一个属性和方法。

function Person(){}Person.prototype.name = "Nicholas";
Person.prototype.sayName = function(){console.log(this.name);
}var person1 = new Person();
var person2 = new Person();console.log(person1.sayName===person2.sayName);//true
console.log(person1.name===person2.name);//true

 4.组合使用构造函数模式和原型模式(混合模式)

但是可以看到,虽然原型模式能够解决固定属性和方法多次复制的问题,如果属性要根据不同实例对象改变,这时候最好还是把会随实例对象改变的属性放置在构造函数内部,这又用到了构造函数模式。将构造函数模式和原型模式相结合,就能利用这两个模式的优势。

function Person(name,age){//会随实例对象改变的属性this.name = name;this.age = age;
}
//不变的属性或者是方法
Person.prototype.job = "Soft Engineer";
Person.prototype.sayName = function(){console.log(this.name);
}var person1 = new Person("Nicholas",28);
var person2 = new Person("Shelby",25);

 

转载于:https://www.cnblogs.com/tisikcci/p/5846844.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/457312.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2016年CCF第七次测试 俄罗斯方块

1 //2016年CCF第七次测试 俄罗斯方块2 // 这道小模拟题还是不错3 // 思路&#xff1a;处理出输入矩阵中含1格子的行数和列数4 // 再判是否有一个格子碰到底部&#xff0c;否则整体再往下移动一步&#xff0c;如果有一个格子不能移动&#xff0c;要返回到前一步5 6 #include <…

springmvc视图解析器_SpringMVC视图及REST风格

什么是视图解析器&#xff1f;springMVC用于处理视图最重要的两个接口是ViewResolver和View。ViewResolver的主要作用是把一个逻辑上的视图名称解析成一个真的的视图&#xff0c;而SpringMVC中用于把View对象呈现给客户端的是View对象本身&#xff0c;而ViewResolver只是把逻辑…

mysql5.7.x 1251_MySql-8.0.x免安装版下载与配置,Navicat打开数据库链接报错1251的解决办法...

概述MySQL从5.7一下子跳到了MySQL8.0, 其中的变化必然是很大的, 这里就不说了, 本文主要讲解最新版MySQL安装的事情.实际上5.7版本后的mysql免安装版都是没有data文件和my.ini文件的&#xff0c;下面再具体说明怎么生成&#xff0c;注意不能自己手动新建.下载下载程序必然去官网…

To install 64-bit ODBC drivers

为了更充分的利用硬件资源&#xff0c;我想很多人都开使用64位操作系统了&#xff0c;同时你可以也发现了在64位操作系统上ODBC的驱动找不到了&#xff0c;所以ODBC的东西都没法用了。 因为2007以前版本的Office只有32位版本&#xff0c;所以我们不能在64位系统上使用ODBC。使用…

【Qt开发】QTableWidget设置根据内容调整列宽和行高

QTableWidget要调整表格行宽主要涉及以下一个函数 1.resizeColumnsToContents(); 根据内容调整列宽 2.resizeColumnToContents(int col); 根据内容自动调整给定列宽 3.horizontalHeader()->setResizeMode 把给定列…

深入浅出mysql数据开发_深入浅出MySQL数据库开发、优化与管理维护 PDF扫描版[513KB]...

深入浅出MySQL数据库开发、优化与管理维护 内容介绍&#xff1a;本书从数据库的基础、开发、优化、管理维护4个方面对MySQL进行了详细的介绍&#xff0c;其中每一部分都独立成篇。本书内容实用&#xff0c;覆盖广泛&#xff0c;讲解由浅入深&#xff0c;适合于各个层次的读者。…

Understand Lambda Expressions in 3 minutes(翻译)

本文翻译自CodeProject上的一篇简单解释Lambda表达式的文章&#xff0c;适合新手理解。译文后面我补充了一点对Lambda表达式的说明。 1.什么是Lambda表达式&#xff1f; Lambda表达式是一种匿名方法&#xff0c;多数情况下用来在LINQ中快速创建委托。简单地说&#xff0c;它代表…

Hibernate二级缓存配置

一、定义&#xff1a; 二级缓存是进程或集群范围内的缓存&#xff0c;可以被所有的Session共享&#xff0c;是可配置的插件 二、二级缓存原理图 解析&#xff1a;每次从二级缓存中取出的对象&#xff0c;都是一个新的对象。 三、配置步骤如下&#xff1a; 同理&#xff1a;以员…

redis配置主从没效果_跟我一起学Redis之加个哨兵让主从复制更加高可用

Redis哨兵(Sentinel)其实本质就是一个RedisServer节点&#xff0c;通过设置 运行模式 来开启哨兵的功能&#xff1b;主要功能如下&#xff1a;监控(Monitoring )&#xff1a;哨兵节点会不断地检查的主服务和从服务的运行状态&#xff1b;自动故障迁移(Automatic failover) &…

闰秒导致MySQL服务器的CPU sys过高

今天&#xff0c;有个哥们碰到一个问题&#xff0c;他有一个从库&#xff0c;只要是启动MySQL&#xff0c;CPU使用率就非常高&#xff0c;其中sys占比也比较高&#xff0c;具体可见下图。 注意&#xff1a;他的生产环境是物理机&#xff0c;单个CPU&#xff0c;4个Core。 于是&…

position定位——让人又爱又恨的属性

关于css中的position这个属性&#xff0c;在使用的时候&#xff0c;有时很强大&#xff0c;有时又让人很无奈。 强大的时候&#xff0c;对于div中的一些小物件不方便使用margin或者padding的时候&#xff0c;给与position:absolute;再配备left、right、top和bottom&#xff0c;…

CentOS 6.8安装Python2.7.13

转载自&#xff1a;http://www.cnblogs.com/94YY/p/6224441.html查看当前系统中的 Python 版本python --version返回 Python 2.6.6 为正常。检查 CentOS 版本cat /etc/redhat-release返回 CentOS release 6.8 (Final) 为正常。安装所有的开发工具包yum groupinstall -y "D…

新安装数据库sqlserver2008r2,使用javaweb连接不上问题处理

鼠标右键【计算机】--》【管理】&#xff0c;打开界面如下&#xff1a; 选择自己数据库的实例名&#xff1a; 选择TCP/IP&#xff1a;右键【属性】&#xff0c;将所有TCP动态端口的【0】删掉&#xff0c;TCP端口设为1433&#xff1b;重启服务&#xff0c;即可连接。PS:不知道这…

vue 鼠标点击事件_VBA代码解决方案第115讲:点击鼠标实现精准控制触发事件的VBA代码第二方案...

大家好&#xff0c;我们今日继续讲解VBA代码解决方案的第115讲内容&#xff1a;工作表事件中&#xff0c;根据Target参数不同&#xff0c;实现精准控制触发事件的VBA代码第二方案。在上一讲中我们讲了利用Address的属性实现控制触发事件的方案&#xff0c;今日讲解第二方案&…

mysql注入5.0以上_[Injection]对MYSQL 5.0服务器以上版本注入

How to do a SQL Injection for MYSQL Server 5.01. Find a vulnerable add a ‘ at the end of the site example: news.php?id1 add a ‘ at the end of the 1 and see if you get a syntax error2. order by #–Keep upping the # until you get an error.3. union all sel…

动态规划(制表法)模板及应用

int cache[100][100] 初始化为全体为 -1&#xff0c;这样在 cache 中存储的可以是其他任意非负整数&#xff0c;也可以是布尔类型 0/1 &#xff08;true/false&#xff09;&#xff0c;1. 模板 int cache[2500][2500];// 初始化为 -1&#xff0c;memset(cache, -1, sizeof(cach…

(翻译)31天Windows Phone学习-1-项目模板

今天在在外文网站Google关于Windows Phone 7的学习资料&#xff0c;无疑间Google到了Jeff Blankenburg的 31 Days of Windows Phone这个系列&#xff0c;感觉写的比较基础和浅显易懂&#xff0c;适合我这种入们级的人学习&#xff0c;所以准备拿来对Windows Phone 7的简单入门学…

Mssql 跨域查询

有数据库test1和数据库test2。其中test1中有表 table1、table2&#xff1b;test2 中有表 table1。三个表的字段都为为&#xff1a;id、xingming、shijian、shuliang。接下来我们就以上面的条件为例来介绍跨数据库查询和跨表 查询的方法。 SELECT * FROM OPENROWSET(sqloledb…

arch mysql日志位置_MySQL 日志文件与相关参数

1 、参数文件及mysql参数查看mysql 的 my.cnf 配置文件位置命令&#xff1a;>./bin/mysql --help | grep my.cnf查看mysql 的参数设置命令&#xff1a; mysql > show variables --显示所有参数; // show variables like log_error% 显示某匹配参数mysql > select se…

MOSS点滴(2):自定义Application Page

在MOSS中后台管理的页面都是Application Page&#xff0c;比如网站设置的页面(settings.aspx)就是典型的Application Page&#xff0c;它不能被Sharepoint Desiger定制。如果我们要修改只能手动的使用其他工具来修改&#xff0c;我们也可以添加Application Page&#xff0c;必须…