Wish you a happy day~(❁´◡`❁)

javascript创建对象的7种方式详解

[ 进击的程序媛 ] zoey 990次浏览 2个评论

这篇总结摘自《javascript高级程序设计》第六章第2节。

js创建对象的方式一共有7种,我详细翻阅了红皮书后写了篇总结以便加深印象。js创建对象共有7种方式,分别是:

  • 工厂模式
  • 构造函数模式
  • 原型模式
  • 组合模式(原型&构造函数)
  • 动态原型模式
  • 寄生构造函数模式
  • 稳妥构造函数模式

* 工厂模式 *

示例代码:

工厂模式的缺点:无法解决对象识别的问题(即如何知道一个对象的类型) instanceof、constructor对该种模式的对象都无意义。

因此,构造函数模式应运而生

* 构造函数模式 *

示例代码:

使用new操作符时,经历了以下4个步骤:

  1. 创建一个新对象
  2. 将this指针指向这个新对象
  3. 给新对象添加属性(执行构造函数中的代码)
  4. 返回新对象

返回的新对象 person2_1、person2_2都保留了一个constructor属性执行Person函数,但是如果想要检测类型,还是instanceof比较靠谱(?)

因为一旦重写了构造函数的原型,constructor属性就失效了(原因后面说)

构造函数模式的缺点:无法解决公共方法,例如sayHello函数,每创建一个新对象就会创建一个,创建多个完成同样功能的函数没有必要。如果要将函数挪到构造函数外部,又会污染全局作用域。

原型模式很好的解决了这个问题。

* 原型模式 *

我们创建的每个函数都有一个prototype属性,这个属性指向一个对象,就是原型对象,这个原型对象包含该函数创建的所有实例对象共享的属性和方法,有点类似于Java中的『父类』的定义。

使用原型模式时,如果想要给对象设置独特的属性,只需要重新赋值即可,这时实例对象的属性覆盖了原型对象的属性,原型对象的属性还存在,并没有被删除。想要继续使用原型对象的属性,实例对象使用delete即可(设置为null也不可以)

  • 使用hasOwnProperty可以检测一个属性是存在于实例对象(true)还是存在于原型对象(false);
  • 使用in可以检测一个实例对象或者它的原型对象上有没有相应属性。

hasOwnProperty 与in结合使用,可以判定一个属性是存在于原型对象还是实例对象中。(hasOwnProperty&&in)

可以批量创建原型对象的属性,例如:

但是这样就完全重写了原型对象,尽管通过instanceof还能返回正确的结果,但是使用constructor判定已经无效了。即使在原型对象中重新声明了constructor属性,也无法跟从前一样。 因为实例对象引用的是最初的原型,不是重新赋值之后的原型。

原型模式的缺点:对于引用类型的属性来说问题比较突出。

如果两个Person实例对象操作friends属性,就会发现这个属性是同步变化的。

* 组合模式 *

构造函数模式用于定义实例属性,原型模式用于定义方法和共享属性,二者结合起来可谓集两种模式之长。

这种方式也是应用最广泛的创建自定义类型的方法。

* 动态原型模式 *

所谓动态原型,是为了让一些使用OO语言的程序员更容易构建代码的一种方式,它不再将构造函数和原型分离开,而是封装在一个构造函数中。

注意,在这种模式中不能用字面量重写原型,如果重写原型,会切断现有实例与新原型之间的联系,可以做个试验看一下:

如果使用字面量重写:

* 寄生构造函数模式 *

回顾工厂模式可以看到,寄生模式跟工厂模式就差了一点,就是使用了new操作符。这个模式可以在特殊情况下为对象创建构造函数,例如数组功能的拓展:

* 稳妥构造函数模式 *

这种模式是为了安全出现的。所为稳妥对象,指的是没有公共属性,其方法也不引用this的对象,最大程度上实现封装。

 

 

 

 


喜欢 (0)or分享 (0)