定义类或对象的几种方式

定义类或对象的方式主要有:工厂方式、构造函数方式、原型方式、混合的构造函数/原型方式、动态原型方式和混合工厂方式。

在javascript中,对象的属性可在对象创建后动态定义,所以开发者在初次引入JavaScript时编写类似下面的代码:

完成的功能主要是创建一个Ball对象,然后在设置2个属性:颜色以及重量。最后一个属性实际上指向函数的指针,它其实就是一个方法。执行这段代码后就可以使用Ball对象。但是假如要创建多个对象,这种方法就行不通了。
这个时候工厂函数(factory function)就派上用场了。例如,函数createBall()可用于封装创建Ball对象的操作:

但是存在一个问题,那就是每次创建一个Ball对象时,都需要创建新的函数getColor,意味着每个对象都有自己的getColor()版本,但事实上,每个对象都共享了同一个函数。
有些开发者在工厂函数外定义对象的方法,然后通过属性指向该方法,从而避开这个问题

在这段重写的代码中,在函数createBall()前定义了showColor()。在createBall内部,赋予对象一个指向已经存在的showColor()函数的指针,从功能上讲,这样解决了重复创建函数对象的问题,但该函数看起来不像对象的方法。
于是构造函数登场了。

特点如下:在构造函数内部无创建对象,而是使用this关键字。使用new运算符调用构造函数时,在执行第一段代码前创建一个对象,只有this才能访问该对象,然后可以直接赋予this属性,默认情况下是构造函数的返回值(不必指明使用return运算符)。但还是存在一个问题,还是会重复生成函数,为每个对象都创建独立的函数版本。不过,与工厂函数相似,也可以用外部函数重写构造函数,但是没什么意义。
那么原型方式是否能解决问题呢?
用空构造函数来设置类名。然后所有属性和方法都被直接赋予prototype属性。代码如下:

看起来是一个非常好的解决方案,但还是有缺憾。
第一,这个构造函数没有参数,使用原型方式不能给构造函数传递参数初始化属性。
第二,在属性指向的是对象时,而不是函数时。函数共享不会造成任何的问题,但对象却很少是被多个实例共享的。考虑下面的代码:

 

这里owers是实现Array对象的指针,该数组包含两个名字”Mike”和”LiLi”。由于owers是引用值,Ball的两个实例都指向同一个数组。这意味着oBall1.owers添加值”Kevin”,在oBall2.owers中也可以看到。
那是否还有更好的解决办法呢?答案是有的。
混合的构造函数/原型方式
联合使用构造函数和原型方式。即用构造函数定义对象的所有非函数属性,用原型方式定义对象的函数属性(方法)。结果是所有函数都只创建一次。而每个对象都具有自己的对象属性实例。代码如下:

动态原型模式其实是和混合构造函数/原型模式差不多的,即在构造函数内定义非函数属性,而函数属性则利用原型属性定义,唯一的区别是赋予对象方法的位置。
关键点:判断Ball._intialized值的情况。
最后介绍一种方式:混合工厂方式
目的是构造假构造函数,只返回另一种对象的实例。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值