JavaScript 对象创建的六种方式详解

作者:异步漫步

时间:2026-10-28

浏览:581

本文系统介绍了 JavaScript 中定义对象的六种主要方式,包括工厂模式、构造函数模式、原型模式、混合构造函数/原型模式、动态原型模式以及混合工厂模式。通过对比各模式的代码实现、内存占用及属性共享机制,重点解析了原型链中引用类型属性的潜在问题,并推荐混合构造函数/原型模式为当前最广泛使用的最佳实践。

文章目录

在 JavaScript 中,定义类或对象的方式多种多样。


1、工厂方式

工厂方式

function Car(){


var ocar = new Object;


ocar.color = "blue";


ocar.doors = 4;


ocar.showColor = function(){


document.write(this.color)


   };

return ocar;


  }

var car1 = Car();


var car2 = Car();



调用该函数时会创建新对象,并赋予其所有属性和方法。利用这种方式可以生成两个属性完全相同的对象。当然,也可以通过传递参数来改进这种模式。



function Car(color,door){


var ocar = new Object;


ocar.color = color;


ocar.doors = door;


ocar.showColor = function(){


document.write(this.color)


   };

return ocar;


  }

var car1 = Car("red",4);


var car2 = Car("blue",4);


car1.showColor() //output:"red"


car2.showColor() //output:"blue"



现在,可以通过向函数传递不同的参数来获取具有不同属性值的对象实例。



在前面的示例中,每次调用 Car() 函数时,都会重新创建 showColor() 方法,这意味着每个对象都拥有自己独立的 showColor() 方法副本。


然而事实上,每个对象本应共享同一个函数逻辑。



虽然可以在函数外部定义方法,然后将函数的属性指向该方法,



function showColor(){


alert(this.color);


  }

function Car(){


var ocar = new Object();


ocar.color = color;


ocar.doors = door;


ocar.showColor = showColor;


return ocar;


  }

但这种方式在语义上看起来不太像函数的方法。



2、构造函数方式

构造函数方式与工厂方式类似,实现起来同样简单,代码如下:



构造函数方式

function Car(color,door){


this.color = color;


this.doors = door;


this.showColor = function(){


alert(this.color)


   };
  }

var car1 = new Car("red",4);


var car2 = new Car("blue",4);



可以看到,构造函数方式在函数内部并未显式创建对象,而是使用 this 关键字。因为在调用构造函数时已经创建了对象,所以在函数内部只能通过 this 来访问对象的属性。



现在使用 new 关键字来创建对象,看起来更加规范了!但它与工厂方式存在相同的问题:每次调用构造函数都会为对象创建独立的方法实例。



3、原型方式

该方式利用了对象的 prototype 属性。首先使用一个空函数创建类名,然后将所有的属性和方法都赋予 prototype 属性。



原型方式

function Car(){


  }

Car.prototype.color = "red";


Car.prototype.doors = 4;


Car.prototype.showColor = function(){


alert(this.color);


  }

var car1 = new Car();


var car2 = new Car();



在这段代码中,首先定义了一个空函数,然后通过 prototype 属性来定义对象的属性。调用该函数时,原型的所有属性都会立即赋予新创建的对象。因此,该函数的所有对象实例存放的都是指向 showColor() 的指针,从语法上看,它们似乎属于同一个对象。



然而,这种函数没有参数,无法通过传递参数来初始化属性,必须在对象创建后才能修改属性的默认值。



原型方式存在一个严重的问题,即当属性指向的是对象(如数组)时。



function Car(){


  }

Car.prototype.color = "red";


Car.prototype.doors = 4;


Car.prototype.arr = new Array("a","b");


Car.prototype.showColor = function(){


alert(this.color);


  }

var car1 = new Car();


var car2 = new Car();



car1.arr.push("cc");



alert(car1.arr); //output:aa,bb,cc


alert(car2.arr); //output:aa,bb,cc



由于数组是引用类型,Car 的两个对象实例指向的是同一个数组。因此,当在 car1 中添加值后,在 car2 中也能看到该变化。



4、混合的构造函数/原型方式

混合使用构造函数和原型方式,就可以像其他程序设计语言一样创建对象:使用构造函数定义对象的非函数属性,使用原型方式定义对象的方法。



混合构造函数/原型方式

function Car(color,door){


this.color = color;


this.doors = door;


this.arr = new Array("aa","bb");


  }

Car.prototype.showColor(){


alert(this.color);


  }

var car1 = new Car("red",4);


var car2 = new Car("blue",4);



car1.arr.push("cc");



alert(car1.arr); //output:aa,bb,cc


alert(car2.arr); //output:aa,bb



  
5、动态原型方式

动态原型方式与混合构造函数/原型方式的原理相似。唯一的区别在于赋予对象方法的位置。



动态原型方式

function Car(color,door){


this.color = color;


this.doors = door;


this.arr = new Array("aa","bb");



if(typeof Car._initialized == "undefined"){


Car.prototype.showColor = function(){


alert(this.color);


    };

Car._initialized = true;


   }
  }

动态原型方式使用一个标志位来判断是否已经给原型赋予了方法。这样可以保证该方法只创建一次。



6、混合工厂方式

它的目的是创建假构造函数,仅返回另一种对象的新实例。



混合工厂方式

function Car(){


var ocar = new Object();


ocar.color = "red";


ocar.doors = 4;


ocar.showColor = function(){


alert(this.color)


   };

return ocar;


  }

与工厂方式不同的是,这种方式使用了 new 运算符。



  

以上就是所有的对象创建方法。目前使用最广泛的是混合构造函数/原型方式,此外,动态原型方式也很流行,在功能上与构造函数/原型方式等价。


实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章