JavaScript对象创建的七种模式详解

作者:异步漫步

时间:2026-10-30

浏览:281

本文系统总结了JavaScript中创建对象的七种常用模式,包括工厂模式、构造函数模式、原型模式及其组合方式。详细解析了动态原型、寄生构造函数和稳妥构造函数模式的适用场景与局限性,帮助开发者根据具体需求选择最合适的对象创建方案。

文章目录

本文通过具体实例,全面梳理了JavaScript中创建对象的各类模式,旨在为开发者提供实用的参考指南。

在JavaScript中,创建对象是一项基础且简单的操作,开发者既可以使用对象字面量语法,也可以利用构造函数来实现。目前业界常用的对象创建模式主要包含以下几种类型。

工厂模式

一、工厂模式

工厂模式的核心思想在于抽象具体对象的创建过程,通过封装函数来隐藏创建对象的具体细节,从而提供统一的接口。


function createAnimal(name, age) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.sayName = function() {
    alert(this.name);
  }
  return o;
}
var cat = createAnimal("cat", 12);
var dog = createAnimal("dog", 3);

尽管工厂模式有效解决了创建多个相似对象时代码重复的问题,但它存在一个明显的缺陷:无法解决对象识别(Object Identification)的问题,即无法准确判断对象的具体类型。

构造函数模式

二、构造函数模式

构造函数模式允许开发者创建具有特定类型的对象,从而弥补了工厂模式的不足。


function Animal(name, age) {
  this.name = name;
  this.age = age;
  this.sayName = function() {
    alert(this.name);
  }
}
var cat = new Animal("cat", 12);
var dog = new Animal("dog", 3);

在构造函数模式下,可以通过对象的constructor属性或者instanceof操作符来准确标识和判断对象的类型。


cat.constructor == Animal // true
cat instanceof Animal // true

原型模式

三、原型模式

在JavaScript中,每个函数都拥有一个prototype(原型)属性。该属性是一个指针,指向一个对象,这个对象包含了可以由特定类型的所有实例共享的属性和方法。

使用原型对象的主要优势在于,它允许所有对象实例共享其所包含的属性和方法,从而节省内存空间。


function Animal() {}
Animal.prototype.name = "animal";
Animal.prototype.age = 1;
Animal.prototype.sayName = function() {
  alert(this.name);
}
var test1 = new Animal();
test1.sayName(); // "animal"
var test2 = new Animal();
test2.sayName(); // "animal"
alert(test1.sayName === test2.sayName); // true

另一种写法如下所示:


function Animal() {}
Animal.prototype = {
  constructor: Animal,
  name: "animal",
  age: 1,
  sayName: function() {
    alert(this.name);
  }
};

原型中的所有属性都被多个实例共享。如果在实例上添加一个与原型属性同名的属性,将会隐藏原型中的对应属性。然而,当属性值包含引用类型(如数组或对象)时,问题便会显现,具体表现如下:


function Animal() {}
Animal.prototype = {
  constructor: Animal,
  name: "animal",
  age: 1,
  hobbies: ["dance", "sing", "play"],
  sayName: function() {
    alert(this.name);
  }
};
var cat = new Animal();
var dog = new Animal();
cat.hobbies.push("sleep");
alert(cat.hobbies); // "dance", "sing", "play", "sleep"
alert(dog.hobbies); // "dance", "sing", "play", "sleep"
alert(cat.hobbies === dog.hobbies); // true

组合使用构造函数模式和原型模式

四、组合使用构造函数模式和原型模式


function Animal(name, age) {
  this.name = "animal";
  this.age = 1;
  this.hobbies = ["dance", "sing", "play"];
}
Animal.prototype = {
  constructor: Animal,
  sayName: function() {
    alert(this.name);
  }
};
var cat = new Animal("cat", 2);
var dog = new Animal("dog", 3);
cat.hobbies.push("sleep");
alert(cat.hobbies); // "dance", "sing", "play", "sleep"
alert(dog.hobbies); // "dance", "sing", "play"
alert(cat.hobbies === dog.hobbies); // false
alert(cat.sayName === dog.sayName); // true

动态原型模式

五、动态原型模式


function Animal(name, age) {
  this.name = name;
  this.age = age;
  if(typeof this.sayName != "function") {
    Animal.prototype.sayName = function() {
      alert(this.name);
    }
  }
}
var cat = new Animal("cat", 12);
cat.sayName(); // "cat"

在使用动态原型模式时,严禁使用对象字面量语法来重写原型。如果在已经创建了实例的情况下重写原型,将会切断现有实例与新原型之间的联系,导致实例无法访问新方法。

寄生构造函数模式

六、寄生构造函数模式

寄生构造函数模式的基本理念是创建一个函数,该函数的作用仅仅是封装创建对象的代码,随后返回新创建的对象实例。

从表面形式看,这个函数与典型的构造函数非常相似,唯一的区别在于使用了new操作符。此外,该模式与工厂模式在实现上几乎一模一样。需要注意的是,构造函数在不显式返回值的情况下,默认会返回新对象实例;而通过在构造函数末尾添加return语句,可以重写调用构造函数时的返回值。


function Animal(name, age) {
  var o = new Object();
  o.name = name;
  o.age = age;
  o.sayName = function() {
    alert(this.name);
  }
  return o;
}
var cat = new Animal("cat", 12);
cat.sayName(); // "cat"

由于返回的对象与构造函数本身或构造函数的原型之间缺乏直接关联,因此不能依赖instanceof操作符来确定对象的类型。

建议在可以使用其他模式的情况下,尽量避免使用这种模式。

稳妥构造函数模式

七、稳妥构造函数模式

稳妥构造函数模式与寄生构造函数模式类似,但存在两点关键差异:

第一,新创建对象的实例方法不再引用this关键字;

第二,不使用new操作符来调用构造函数。


function Animal(name, age) {
  var o = new Object();
  o.name = name;
  o.age = age;
  var msg = "Hello, I'm ";
  o.sayName = function() {
    alert(msg + this.name);
  }
  return o;
}
var cat = new Animal("cat", 12);
cat.sayName(); // "Hello, I'm cat"

稳妥构造函数模式适用于某些对安全性要求较高的执行环境。

更多关于JavaScript相关内容可查看本站专题:《javascript面向对象入门教程》、《JavaScript中json操作技巧总结》、《JavaScript切换特效与技巧总结》、《JavaScript查找算法技巧总结》、《JavaScript动画特效与技巧汇总》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述的JavaScript对象创建模式分析,能对大家的程序设计工作有所帮助。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章