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

作者:纸飞机时间:2026-10-30 06:22:42浏览:72

本文深入解析JavaScript中创建对象的七种主要模式,包括工厂模式、构造函数模式、原型模式及其优缺点。重点探讨如何解决对象识别与方法复用问题,并详细介绍组合使用构造函数和原型模式、动态原型模式、寄生及稳妥构造函数模式,帮助开发者根据场景选择最优方案。

工厂模式

一、工厂模式


function person (name,age) {
  var p=new Object();
  p.name=name;
  p.age=age;
  p.showMessage=function(){
    console.log("name:"+this.name+" age:"+this.age);
  }
  return p;
}
var p1=person("k1",28);
var p2=person("k2",29);
console.log(p1.showMessage==p2.showMessage);//false 不是同一个showMessage方法
console.log(p1.constructor);//[object] 都是object

该模式的主要缺陷在于无法解决对象识别问题,且每个实例的 showMessage 方法都是独立创建的,导致内存开销增加。

构造函数模式

二、构造函数模式


function Person (name,age) {
  this.name=name;
  this.age=age;
  this.showMessage=function(){
    console.log("name:"+this.name+" age:"+this.age);
  }
}
var p1=new Person("k1",28);
var p2=new Person("k2",29);
console.log(p1.showMessage==p2.showMessage);//false 不是同一个showMessage方法
console.log(p1.constructor);//[Person]
console.log(p1 instanceof Person);// true

此模式解决了对象识别问题,但每个实例的 showMessage 方法依然各自独立,存在重复创建带来的性能开销。

原型模式

三、原型模式


function Person () {
  
}
Person.prototype.name ="k";
Person.prototype.age =29;
Person.prototype.showMessage=function () {
  console.log("name:"+this.name+" age:"+this.age);
};

var p1=new Person();
p1.showMessage();//name:k age:29

var p2=new Person();
p2.showMessage();//name:k age:29

console.log(p1.showMessage==p2.showMessage);// true --引用的是同一函数
console.log(p1.constructor)//[Person] --对象识别
console.log(p1 instanceof Person)//true --对象识别
console.log(Person.prototype.isPrototypeOf(p1));// true
console.log(Object.getPrototypeOf(p1)==Person.prototype);// true

原型模式成功解决了方法重复创建的问题,同时也实现了对象识别。

然而,原型模式存在显著缺陷:挂载在 prototype 上的所有属性、变量和函数被所有实例共享。虽然可以通过实例 p1、p2 访问 prototype 的属性,但无法直接修改属性值。例如执行 p1.name="k1" 时,仅在 p1 实例上新增 name 属性,并未修改 prototype.name。对于值类型影响不大,但引用类型会引发问题,具体见如下示例。


function Person () {  
};
Person.prototype.age =10;
Person.prototype.array=[1,2,3];

var p1=new Person();
var p2=new Person();
console.log(p1.array);// [1,2,3]
console.log(p2.array); //[1,2,3]
p1.array.push(4);
console.log(p1.array);//[1,2,3,4]
console.log(p2.array);//[1,2,3,4]

当 p1 向 array 添加值时,p2 也会反映该变化,因为两者指向同一个 array 对象。

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

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

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


function Person (name,age) {
  this.name=name;
  this.age=age;
}

Person.prototype.showMessage = function() {
  console.log("name:"+this.name+" age:"+this.age);
};

var p1=new Person("k",30);
p1.showMessage();

动态原型模式

五、动态原型模式

该模式旨在将所有信息封装在构造函数中,更符合面向对象(OO)的设计思想。


function Person (name,age) {
  this.name=name;
  this.age=age;
  if(typeof this.showMessage!="function"){
    Person.prototype.showMessage=function(){
      console.log("name:"+this.name+" age:"+this.age);
    }
  }
}

var p1=new Person("k",30);
p1.showMessage();

寄生构造函数模式

六、寄生构造函数模式


function Person (name,age) {
  var o=new Object();
  o.name=name;
  o.age=age;
  o.sayName=function(){
    console.log(this.name);
  };
  return o;
}
var p1=new Person("k",28);
p1.sayName();

寄生构造函数模式与工厂模式完全一致,区别在于创建对象时使用了 new 关键字,例如:var p1=new Person("k",28)。

其主要作用是在构造函数内部进行功能扩展。例如,定义一个基于 Array 数组的自定义类型 MyArray,并拥有自己的方法,如下所示。


function MyArray(){
  var values=new Array();
  values.push.apply(values,arguments);
  //自己定义的方法
  values.toPipedString=function(){ 
    return this.join('|');
  };
  return values;
}
var colors=new MyArray("red","blue","green");
console.log(colors.toPipedString());
console.log(colors instanceof Array);

稳妥构造函数模式

七、稳妥构造函数模式

稳妥构造函数遵循与寄生构造函数类似的模式,但有两点不同:一是不使用 this,二是不使用 new 调用构造函数。


function Person (name,age) {
  var o=new Object();
  var tempAge=age;

  o.name=name;
  o.age=age;

  o.sayName=function(){
    console.log(name);
  }
  o.sayAge=function(){
    console.log(tempAge);
  }
  return o;
}

var p1=Person("k1",28);
p1.sayName(); // k1
p1.sayAge(); // 28

p1.name="k2";
p1.age=30;
p1.sayName(); // k1
p1.sayAge();  //28

通过上述输出可以清晰理解稳妥对象模式的含义:使用该模式创建的对象,除了初始化时传入的值(如 Person("k1",28))外,没有其他办法能改变其状态。这种对象即为稳妥对象,其实现原理依赖于 JavaScript 的闭包机制。

以上关于创建 JavaScript 对象方法的浅析内容分享完毕,希望能为大家提供参考,也希望大家多多支持本站。

作者最新文章