JavaScript原型模式详解:共享属性与屏蔽机制
本文深入解析JavaScript原型模式,阐述prototype属性的共享机制及原型链搜索规则。通过构造函数示例,说明实例如何访问原型方法,并重点分析当实例属性与原型属性同名时产生的屏蔽效应,帮助开发者理解对象属性的优先级与内存共享原理。
原型模式基础与共享机制
在JavaScript中,每个函数都拥有一个名为prototype(原型)的属性,该属性是一个对象,包含了特定类型所有实例可以共享的属性和方法。利用这一机制的优势在于,无需在构造函数内部逐一定义对象信息,而是可以直接将这些共享的属性和方法添加到原型对象中。以下示例延续前文逻辑进行演示:
代码如下:
function Employee() {
};
Employee.prototype.Name = "Jim";
Employee.prototype.Age = 28;
Employee.prototype.Job = "SoftWare Engineer";
Employee.prototype.SayName = function () {
alert(this.Name);
};
var employee1 = new Employee();
employee1.SayName();//Jim
var emplayee2 = new Employee();
emplayee2.SayName(); //Jim
alert(employee1.SayName = emplayee2.SayName);//true 与传统的构造函数模式不同,通过原型模式创建的新对象,其属性和方法由所有实例共同共享。
上述内容构成了原型模式的初步概念。若要深入理解其工作原理,必须掌握ECMASCRIPT规范中关于原型的底层性质。
深入理解原型链与属性搜索
理解原型
在JavaScript中,只要定义了一个新函数,系统就会依据特定规则为该函数创建一个prototype属性。默认情况下,该属性会自动获得一个constructor属性,该属性包含一个指向定义该prototype属性的函数的指针。借助这个构造函数,可以继续为原型对象添加其他属性和方法。
自定义构造函数创建后,其原型属性默认仅包含constructor属性,其他方法均从Object继承而来。当通过构造函数创建新实例时,该实例内部会包含一个指向构造函数原型属性的指针(内部属性)。需特别注意,这一连接存在于实例与构造函数的原型属性之间,而非实例与构造函数本身之间。
尽管在某些实现中无法直接访问内部属性(即_proto_属性),但在所有实现中均可通过isPrototypeOf方法来确定对象间是否存在这种原型关系。从本质上看,若对象的_proto_属性指向isPrototypeOf,该方法将返回true。示例如下:
代码如下:
alert(Employee.prototype.isPrototypeOf(employee1)); //true
alert(Employee.prototype.isPrototypeOf(employee2));//true 每当代码读取对象的某个属性时,都会执行一次搜索,目标是寻找具有指定名称的属性。搜索过程首先从对象实例本身开始。若在实例中找到具有指定名称的属性,则直接返回该属性的值;若未找到,则继续沿着指针指向的原型对象进行搜索,在原型对象中查找具有指定名称的属性。若在原型对象中找到该属性,则返回其值。这正是多个对象实例能够共享原型所保存的属性和方法的基本原理。
前文提及,原型最初仅包含constructor属性,且该属性是共享的,因此可以通过对象实例直接访问。
原型属性屏蔽效应分析
虽然可以通过对象实例访问保存在原型中的值,但不能通过对象实例直接重写原型中的值。如果在实例中添加一个属性,且该属性名称与原型中的一个属性名称相同,那么在实例中创建的属性会屏蔽(在某些语言中称为隐藏)原型中的同名属性。示例如下:
代码如下:
function Employee() {
};
Employee.prototype.Name = "Jim";
Employee.prototype.Age = 28;
Employee.prototype.Job = "SoftWare Engineer";
Employee.prototype.SayName = function () {
alert(this.Name);
};
emplayee2.Name = "Sun";
alert(employee1.Name); //Jim
alert(employee2.Name);//Sun 其中,employee1.Name的值Jim来源于原型,而employee2.Name的值Sun来源于实例本身。
D3.js 比例尺与坐标轴的配置详解
2026-11-05 16:54:46
JavaScript怎么遍历对象的Symbol键和不可枚举属性
2026-11-05 13:13:39
封装一个健壮的JS字符串判空工具函数
2026-11-05 12:16:14
JavaScript合并数组的三种常用方法:concat、扩展运算符与push
2026-11-05 11:22:29
JavaScript立即执行函数(IIFE)是什么及基本语法
2026-11-05 10:51:19
