JavaScript 面向对象:5种创建对象的方法详解

作者:函数茶馆时间:2026-10-27 05:13:16浏览:168

本文系统总结了JavaScript中创建对象的五种核心模式:对象字面量、Object实例、工厂模式、构造函数模式以及原型模式,并深入解析了构造-原型组合模式。通过对比各模式的优缺点,如类型识别、内存共享及属性封装等,帮助开发者根据实际需求选择最合适的对象创建方案,掌握JS面向对象编程的基础与进阶技巧。

JavaScript对象创建基础

在JavaScript中,创建对象是面向对象编程的基础步骤。



第一种方法:使用对象字面量。


具体代码实现如下:

 
var clock={
hour:12,
minute:10,
second:10,
showTime:function(){
alert(this.hour+":"+this.minute+":"+this.second);
} 
} 
clock.showTime();//调用

第二种方法:通过创建Object实例来构建对象。


具体代码实现如下:

 
var clock = new Object();
clock.hour=12;
clock.minute=10;
clock.showHour=function(){alert(clock.hour);};
clock.showHour();//调用

由此可见,对象的属性可以在运行时动态地添加和修改。





常见对象创建模式

接下来介绍几种对象创建的设计模式:



1. 工厂模式:这是一种通过函数接收参数并返回新对象的方式,类似于流水线生产。


具体代码实现如下:

 
function createClock(hour,minute,second){
var clock = new Object();
clock.hour=hour;
clock.minute=minute;
clock.second=second;
clock.showHour=function(){
alert(this.hour+":"+this.minute+":"+this.second);
}; 
return clock;
}; 
var newClock = createClock(12,12,12);//实例化
newClock.showHour();//调用

该模式的优点在于实现了抽象概念,但其缺点是无法识别对象的具体类型。



2. 构造函数模式:通过构造函数直接创建对象。


具体代码实现如下:

 
function clock(hour,minute,second){
this.hour = hour;
this.minute = minute;
this.second = second;
this.showTime = function(){
alert(this.hour+":"+this.minute+":"+this.second);
} 
} 
var newClock =new clock(12,12,12);
alert(newClock.hour);

注意:使用new关键字是必须的。如果省略,clock将作为普通函数执行,且其内部的this会指向外部作用域(如window),从而意外地向全局对象添加属性。为确保安全,建议采用以下写法:


具体代码实现如下:

 
function clock(hour,minute,second){
if(this instanceof clock){
this.hour = hour;
this.minute = minute;
this.second = second;
this.showTime = function(){
alert(this.hour+":"+this.minute+":"+this.second);
} 
} 
else{
throw new Error("please add 'new' to make a instance");
} 
} 

构造函数模式的缺点在于,每次创建实例时都会重新创建方法,导致内存浪费。例如,n个实例会创建n份相同的方法副本。为了解决这个问题,引入了原型模式。



原型模式深入解析

3. 原型模式:利用prototype属性共享方法和属性。


具体代码实现如下:

 
function clock(hour,minute,second){
} 
clock.prototype.hour=12;
clock.prototype.minute=12;
clock.prototype.second=12;
clock.prototype.showTime=function(){
alert(this.hour+":"+this.minute+":"+this.second);
} 
var newClock = new clock();
newClock.showTime();

深入理解原型模型至关重要。



每个函数都拥有一个prototype属性,该指针指向clock.prototype对象。默认情况下,原型对象包含一个constructor属性,指向clock,且该属性可读可写。当实例化对象时,新对象newClock除了拥有构造函数中定义的属性和方法外,还拥有一个指向构造函数的原型的内部指针[[prototype]]。因此,原型对象的方法并未直接存在于具体实例中,因为原型本身未被实例化。



因此,这种模式定义的对象在调用方法时的查找过程为:调用newClock.showTime()时,首先检查实例中是否存在该方法;若存在则调用;若不存在,则沿原型链向上查找;若原型中也不存在,则抛出错误。



此外,还可以采用以下写法:


具体代码实现如下:

 
function clock(hour,minute,second){
} 
clock.prototype={
constructor:clock, //必须手动设置这个属性,不然就断了与构造函数的联系了。没有实例共享原型的意义了。
hour:12,
minute:12,
second:12,
showTime:function(){
alert(this.hour+":"+this.minute+":"+this.second)
} 
} 
var newClock = new clock();
newClock.showTime();

注意:实例与构造函数原型之间的联系也是通过指针建立的,因此可以动态地添加或修改原型中的方法。



纯原型模式的问题在于,所有属性和方法都是共享的,无法实现对象的具体化。通常我们希望每个对象拥有独立的属性。因此,结合前两种模式,产生了新的组合模式。



构造-原型组合模式

4. 构造-原型组合模式:结合构造函数和原型的优点。


具体代码实现如下:

 
function clock(hour,minute,second){
this.hour = hour;
this.minute = minute;
this.second = second;
} 
clock.prototype.showTime=function(){alert(this.hour+":"+this.minute+":"+this.second);}
var newClock = new clock(12,12,12);
newClock.showTime();

在此模式中,我们将属性定义在构造函数中,使对象更具具体性,而将方法定义在原型中,实现共享。

作者最新文章