[JS设计模式]Prototype Pattern

Prototype pattern

Prototype pattern可便于同类型的多个对象共享属性。原型(prototype)是JS原生的对象,其他对象可以通过原型链(prototype chain)来访问原型。单独看这句描述可能还是有点儿抽象,下面通过具体的示例来详细阐述。

javascript 复制代码
class Dog {
	constructor(name) {
		this.name = name;
	}

	bark() {
		return `Woof!`;
	}
}

const dog1 = new Dog("Kadi");
console.log(dog1.__proto__);
console.log(Dog.prototype);

这里可以看到,constructor有一个name属性;根据ES6类的语法规则,所有在类中定义的属性(本例的属性bark),都自动加入到类的prototype中,Dog类本身有两个属性:constructor和bark。

有两种方式可以查看类的原型中的属性 ,一种是通过类本身的prototype,另一种是通过实例的__proto__。

从上图的调试信息可以看到,Dog类的prototype也是一个object,其中有两个属性bark和constructor,另外还有一个原型对象(\[Prototype])。

通常类的实例的__proto__直接引用类的prototype,如果类本身不包含某个属性,JS就会向下搜索原型链,查看在原型链中是否能找到被访问的属性。而在dog1实例中,发现有两个\[prototype],而且还有包含关系,这就是所谓的原型链。

因为所有实例都可以访问类的原型对象,因此原型模式使得实例在访问相同属性时,不用每次都创建该属性的副本。只需要将属性加入到原型中,则所有的实例都可以访问。另外,在创建实例对象后,也支持添加新的属性到原型中,其他实例对象也可以访问这个新加入的属性。

javascript 复制代码
const dog2 = new Dog("Husky")
Dog.prototype.play = ()=> console.log(`playing`);
dog1.play();

我们再创建一个"Husky"的实例,然后对Dog类的原型添加一个新的属性play,接着通过dog1实例来调用play函数,看能否正常运行。


从运行结果来看,dog1能正常访问play属性。

再举个例子,定义一个SuperDog并继承Dog,SuperDog有一个fly属性。通过创建一个SuperDog的实例dog3,且dog3调用bark属性

javascript 复制代码
class SuperDog extends Dog {
	constructor(name) {
		super(name);
	}

	fly() {
		console.log("Flying!");
	}
}

const dog3 = new SuperDog("Super")
dog3.fly();
dog3.bark();
console.log(dog3.__proto__);

此示例中有3级原型链,实例访问属性的搜索路径也非常清晰。dog3.proto -> SuperDog.prototype -> Dog.prototype。

完整示例代码

javascript 复制代码
class Dog {
	constructor(name) {
		this.name = name;
	}

	bark() {
		console.log("Woof!");
	}
}

class SuperDog extends Dog {
	constructor(name) {
		super(name);
	}

	fly() {
		console.log("Flying!");
	}
}

const dog1 = new Dog("Kadi");
console.log(dog1.__proto__);
console.log(Dog.prototype);

const dog2 = new Dog("Husky")
Dog.prototype.play = ()=> console.log(`playing`);

dog1.play();

const dog3 = new SuperDog("Super")
dog3.fly();
dog3.bark();
console.log(dog3.__proto__);

debugger
相关推荐
Dream-Y.ocean8 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
Highcharts.js9 小时前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
kyriewen12 小时前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
工控丫丫13 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库
Dream-Y.ocean16 小时前
鸿蒙PC平台星图遥感适配实战:基于 Electron 壳方案的纯 JavaScript 遥感图像处理引擎开发
javascript·electron·harmonyos
螺丝钉tina16 小时前
[Playwright ][16]Playwright + TypeScript API 自动化测试实战:API测试
前端·javascript·typescript
拆房老料16 小时前
DeepSeek Super-agent 架构解析:从单任务 Agent 到持续运行的任务系统
人工智能·设计模式·系统架构
Highcharts.js18 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
Java后端的Ai之路19 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
薛定谔的猫-菜鸟程序员19 小时前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron