JS面向对象——之创建对象的几种构造模式讲解

原创 296842176 随笔 技术经验 346阅读 2017-05-26 17:00:54 举报

一、工厂模式
以函数来封装一特定接口创建的对象,来看看案例代码:
html 代码

这种模式解决了创建多个相似对象的问题(通过传参),但是没有解决对象识别问题(没有特定的类型);
通过下面的alert可以看出,创建的对象并没有一个指定的类型。可与下面构造模式做一个比较。
Ps:instanceof操作符也是来检测对象类型。

二、构造函数模式
创建自定义构造函数,从而自定义对象的属性和方法。例子如下:

html 代码

构造函数模式相比较工厂模式:1没有显式创建对象;2直接将属性方法赋给了this对象;3没有return语句。
创建对象实例,要使用new操作符。
以 var person1 =new Person('小明', '22', '前端工程师');实例化为例,调用构造函数会经历以下四个步骤:
1.创建一个新对象(person1);
2.将构造函数作用于给新对象(此时this指向了新对象person1);
3.执行构造函数代码(读取参数为新对象添加属性);
4.返回新对象。
Ps:基于其他OO语言的惯例构造函数首字母大写,Person区别于普通函数,这样比较规范。
通过比较两种模式检测的对象类型,可以看出构造函数模式可以将他的实例标识为一种特定的类型(此时是Person);这是构造函数模式的优势。
检测是实例类型还包括Object,是因为所有对象都继承自Object。
构造函数的劣势:
正如最后也个alert弹出的false,构造函数每个方法都要在每个实例中创建一次,创建完成相同任务的函数实例确实没有必要。
通过把sayname()定义拿到构造函数外部,构造函数内部把sayname属性设置成全局函数sayname,解决了多个函数做同一件事的问题;但是对象定义多个方法要创建多个全局函数,这使得自定义的引用类型缺乏封装性。这些问题可以由原型模式解决。
html 代码

三、原型模式
每创建一个函数都有一个prototype(原型)属性,将属性方法存入prototype(原型)里,可以向所有的对象实例共享这些属性方法。这时的所有属性方法都存在prototype中,构造函数变成了空函数。如下所示:
html 代码

Ps:给对象实例添加与构造函数原型同名的属性,添加的属性将屏蔽掉原型里的属性值,打印该属性会显示添加的值。
原型模式的问题:1.省略了构造函数传递初始化参数的环节,所有实例只能读取相同属性值;2.对于包含引用类型值的属性容易出现以下问题。
html 代码

只在person1的数组中追加了值,结果改变了原型中的值,从而影响了person2.

四、组合使用构造函数模式和原型模式
总结一下:1.构造函数模式可以传递初始化参数,实现创建多个相似对象,并且可以将实例标识为一个一种特定类型;但是在对象实例中将创建多个实现相同功能的方法函数。
2.原型模式可以共享实例中的方法和属性;但是能传递初始化参数。
他们的特性完美互补,结合使用,不就接近完美了?看如下代码:
html 代码

五、动态原型模式
构造函数和原型独立存在,封装性还是不够好,通过动态原型模式,将所有信息都封装在构造函数里,通过构造函数初始化原型,又保持了构造函数和原型的优点。
html 代码

注意判断部分,在sayname()不存在的情况下才会将方法添加到原型中。if检查的是初始化后应该存在的任何属性和方法,不必检查所有属性和方法;检查其中一个即可。
动态原型模式下,不能使用对象字面量重写原型。重写会切断现有实例于新原型之间的联系。

评论 ( 0 )
最新评论
暂无评论

赶紧努力消灭 0 回复