JavaScript创建对象的四种常用模式详解

作者:函数茶馆时间:2026-10-22 20:15:47浏览:591

本文深入解析JavaScript中创建对象的四种核心模式:工厂模式、构造函数模式、原型模式以及组合构造函数与原型模式,并补充动态原型模式。通过对比各模式的优缺点及适用场景,帮助开发者根据实际需求选择最优的对象创建方案,避免内存浪费或实例识别问题。

本文详细阐述了JavaScript中构建对象的四种主流模式,旨在为开发者提供实用的参考与指导。

文章涵盖了JavaScript中几种常见的对象创建方式,具体包括:工厂模式、构造函数模式、原型模式、组合使用构造函数与原型模式,以及动态原型模式。

工厂模式

一、工厂模式

参考以下代码示例:


function getMySon(name,sex){
  var o={};
  o.name=name;
  o.sex=sex;
  o.sayName = function(){
    alert(this.name);
  }
  return o;
}
son1 = getMySon('li ming','male');
son2 = getMySon('li hong','female');

上述即为工厂模式的实现。该模式在函数内部定义一个对象,为其添加属性与方法,最后返回该对象。尽管这种方式简化了对象的创建过程,但存在一个显著缺陷:无法准确判断实例的具体来源。

例如,执行 `son1 instanceof getMySon` 将返回 false。这是因为该实例并非由 `getMySon` 通过 `new` 关键字直接创建,而是由函数内部的局部变量 `o` 生成。因此,工厂模式并不适用于需要区分多种不同对象类型的场景。

那么,如何创建对象才能准确识别实例的来源呢?接下来将介绍构造函数模式。

构造函数模式

二、构造函数模式

参考以下代码:


function getMySon(name,sex){
  this.name = name;
  this.sex = sex;
  this.sayName = function(){
    alert(this.name);
  }
}
son1 = new getMySon('li ming','female');

这就是构造函数模式,注意在调用时必须使用 `new` 关键字。

在执行 new 操作时,系统会经历以下四个步骤:

1. 实例化一个新对象(并将该空对象的 __proto__ 属性指向 getMySon.prototype)。

2. 将构造函数的作用域赋给新对象(此时 `this` 指向该新对象)。

3. 执行构造函数中的代码(通过 this 为新对象添加属性)。

4. 返回新对象。

通过这种方式生成的实例,可以使用 `son1 instanceof getMySon` 来正确判断实例是由哪个构造函数创建的。

然而,构造函数模式也存在一些问题。由于每次使用 `new` 都会创建一个新的对象,导致所有数据在不同实例之间无法共享。对于 `sayName` 这样的函数而言,它并没有必要为每个实例单独创建一份副本,这会造成内存空间的浪费。

这就引出了下一种模式:原型模式。

原型模式

三、原型模式

参考以下代码:


function getMySon(){}
getMySon.prototype.name = 'li ming';
getMySon.prototype.sex = 'female';
getMySon.prototype.sayName = function(){
  alert(this.name);
}

这就是原型模式(关于原型的详细知识此处不再赘述)。

原型模式将属性和方法添加到 getMySon.prototype 中。`prototype` 由所有实例共享,它只存在一份,而不是每个实例各拥有一份。

这种方式实现了函数只保留一份,避免了不必要的空间占用。但是,`name`、`sex` 等属性并不需要在所有实例间共享,而且使用原型模式进行传参以生成这些属性也较为不便。

因此,可以将构造函数模式与原型模式相结合,利用它们各自的优点。让各实例间不需要共享且需通过传参生成的属性放在构造函数模式中生成,而各实例中需要共享(如方法)的部分则在原型模式中定义。

组合构造函数与原型的模式

三、组合构造函数与原型的模式

参考以下代码:


function getMySon(name,sex){
  this.name=name;
  this.sex=sex;
}
getMySon.prototype.sayName(){
  alert(this.name);
}
son1=new getMySon('li ming','female');

这就是组合构造函数与原型的模式。该方式结合了构造函数模式与原型模式的优点,是目前最常用的对象创建模式。

动态原型模式

四、动态原型模式

所谓动态原型模式,实际上是对组合构造函数与原型模式的一种封装。参考以下代码:


function getMySon(name,sex){
  this.name = name;
  this.sex = sex;
  //即使有多个需要定义的方法,也只需判断一个方法。
  if(typeof sayName != 'function'){
    getMySon.prototype.sayName=function(){
      alert(this.name);
    }
  }
}
son1=new getMySon('li ming','female');

之所以称之为动态原型模式,是因为 `getMySon` 在不同调用中行为会发生变化,具有动态性。只有在第一次调用 `getMySon` 时,才会执行对 `sayName` 函数的定义。从本质上看,仍然是将不需共享的属性通过构造函数定义,将需要共享的方法通过原型定义,只是将它们整合在一起进行了封装。

感兴趣的朋友还可以使用本站在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行结果。

更多关于JavaScript相关内容还可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

作者最新文章