JavaScript原型模式与Object.create详解

作者:拾光

时间:2026-10-28

浏览:531

本文深入解析JavaScript中的原型模式,重点介绍如何利用Object.create方法创建可定制的新对象。通过对比不同原型链构建方式,详细阐述实例属性与原型方法的继承差异,并演示子类继承中构造函数调用与原型链设置的正确实践,帮助开发者掌握高效的对象复用技巧。

文章目录

原型模式概述

原型模式概述

核心思路:通过复制现有的原型实例来生成新的、可定制的对象。新对象无需关心原对象的创建细节,直接复用其结构。

基本流程:定义Prototype基类 -> 实例化ProtoExam -> 克隆生成新对象。

相关代码实现如下。

示例代码如下:

function Prototype() {
this.name = '';
this.age = '';
this.sex = '';
}
Prototype.prototype.userInfo = function() {
 return '个人信息, 姓名: '+this.name+', 年龄: '+this.age+', 性别:'+this.sex+'<br />';
}

假设需要创建多个包含不同个人信息的内容对象。


实现代码如下:

var proto = new Prototype();
var person1 = Object.create(proto);
person1.name = '小明';
person1.sex = '男';
person1.age = 35;
person1.userInfo();
//
var person2 = Object.create(proto);
person2.name = '小华';
person2.sex = '女';
person2.age = 33;
person2.userInfo();

最终输出结果如下:


代码执行返回:

个人信息, 姓名: 小明, 年龄: 35, 性别: 男
个人信息, 姓名: 小华, 年龄: 33, 性别: 女

原型模式通常适用于抽象结构复杂但内容组成相似的场景。当新创建的对象只需在原对象基础上进行少量修改即可满足需求时,该模式尤为有效。

Object.create 方法详解

Object.create 方法详解

1. 定义:创建一个指定原型对象,并可包含可选自定义属性的新对象; 2. 语法:Object.create(proto [, properties]); 其中properties为可选参数,用于配置新对象的属性描述符。

具体参数说明如下:

1. proto:必需参数,指定新对象的原型。可为 null。若传入的是已实例化的对象(即经过new创建)或对象的prototype,则具有实际意义;
2. properties:可选参数,结构如下:
{
propField: {
value: 'val'|{}|function(){},
writable: true|false,
enumerable: true|false,
configurable: true|false,
get:function(){return 10},
set:function(value){}
     }
}
自定义属性包含以下四种内置属性:
value:自定义属性的具体值;
writable:标识该项值是否可编辑,默认为 false。当设为 true 时,obj.propField 可被赋值;否则为只读;
enumerable:控制属性是否可枚举;
configurable:控制属性是否可配置(如删除或修改描述符);
此外,还可以包含 get 和 set 访问器方法;
注意:[get, set] 与 value 和 writable 不能同时出现;

1. 创建原型对象类示例:

代码如下:

function ProtoClass(){
this.a = 'ProtoClass';
this.c = {};
this.b = function() {
   }
}

创建原型方法:

示例代码片段

ProtoClass.prototype.aMethod = function() {
//this.a;
//this.b();
return this.a;
}

使用方法演示

1. 以 ProtoClass.prototype 作为原型创建一个对象:

代码如下:

var obj1 = Object.create(ProtoClass.prototype, {
foo:{value: 'obj1', writable: true}
})

obj1 将具备 ProtoClass 原型中的 aMethod 方法;


测试代码如下:

obj1.aMethod();
//输出 undefined,方法可访问,但无法访问 ProtoClass 的实例成员属性

这种方法无法访问 ProtoClass 下的 a, b, c 实例成员属性:

2. 采用实例化的 ProtoClass 对象作为原型:

代码如下:

var proto = new ProtoClass();
var obj2 = Object.create(proto, {
 foo:{value:'obj2'}
});

这样创建的 obj2 将拥有 ProtoClass 的所有成员属性 a, b, c 以及 aMethod 原型方法,并额外添加了一个 foo 只读数据属性;


验证代码如下:

obj2.a; //ProtoClass
obj2.c: //[Object]
obj2.b(); //
obj2.aMethod(); //ProtoClass
obj2.foo; //obj2

3. 子类继承实现:

代码如下:

function SubClass() {
    
}
SubClass.prototype = Object.create(ProtoClass.prototype ,{
foo:{value: 'subclass'}
});
SubClass.prototype.subMethod = function() {
 return this.a || this.foo;
}

这种方法可以继承到 ProtoClass 的 aMethod 方法并执行;

测试代码如下:

var func = new SubClass();
func.aMethod() ;//undefined,无法读取 ProtoClass 的实例成员属性 a,b,c
func.subMethod();//subclass

若要使 SubClass 能读取到 ProtoClass 的实例成员属性,需对 SubClass 构造函数进行修改:

代码如下:

function SubClass()
{
ProtoClass.call(this);
}
//其他代码;

此方法即可获取 ProtoClass 的实例成员属性及原型方法:

验证代码如下:

var func = new SubClass();
func.aMethod() ;//ProtoClass
func.subMethod();//ProtoClass

另一种方法是使用实例化的 ProtoClass 对象作为 SubClass 的原型:

代码如下:

var proto = new ProtoClass();
function SubClass() {
}
SubClass.prototype = Object.create(proto, {
 foo:{value: 'subclass'}
});

这样 SubClass 实例化后,即可获取到 ProtoClass 的所有属性及原型方法,并创建一个只读数据属性 foo;

验证代码如下:

var func = new SubClass();
func.foo; //subclass
func.a; //ProtoClass
func.b(); //
func.c; //[Object]
func.aMethod(); //ProtoClass

4. 另一种创建继承的方法,效果与使用实例化的ProtoClass作为原型一致:

代码如下:

function SubClass() {
this.foo = 'subclass'; //此处属性为可读写
}
SubClass.prototype = new ProtoClass();

Object.create 相关说明

Object.create 用于创建新对象。当传入 Object 时,prototype 为 null,作用等同于 new Object(); 或 {};

当传入 function 时,作用等同于 new FunctionName;

示例代码如下:

//1 Object
var o = {}
//等同于
var o2 = Object.create({});
//两者 constructor 相同;
//-----------------------------------------
function func() {
 this.a = 'func';
}
func.prototype.method = function() {
 return this.a;
}
var newfunc = new func();
//等同于[效果一样]
var newfunc2 = Object.create(Object.prototype/*Function.prototype||function(){}*/, {
 a: {value:'func', writable:true},
 method: {value: function() {return this.a;} }
});

但是 newfunc 与 newfunc2 在创建它们的对象函数引用上存在差异。

newfunc 指向 function func() {...},而 newfunc2 指向 function Function { Native }。

语法说明如下:

Object.create(proto[, propertiesField]):

proto 说明:该值为必需,可为 null。若未设定,将会抛出异常;

proto 为非 null 时,即为已实例化的值(即经过 new 处理的值)。JavaScript 中的对象大多拥有 constructor 属性,该属性表明此对象是由哪个函数实例化而来;

propertiesField 为可选项,用于设定新创建对象可能需要的成员属性或方法;

实用工具推荐

电子包浆

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

使用 ›
图片压缩

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

使用 ›
相关文章