[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
相关推荐
三十而立洋2 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
卡布鲁2 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄2 天前
JavaScript 隐式全局变量解析
javascript
沙蒿同学2 天前
我用 Go 搭了一条 AI Agent 流水线:从 1 张商品图到一整套淘宝详情页
前端·javascript·后端
paopaokaka_luck2 天前
智慧社区综合服务小程序(人脸识别、AI问答、Echarts图形化分析)
前端·javascript·spring boot·spring·数据分析·echarts
Hilaku2 天前
为什么死磕 1px 的团队,用户体验反而更差?
前端·javascript·程序员
Zane19942 天前
一个 new 就能创建对象,为什么还要拆出单例、工厂、建造者、原型四种模式?
设计模式
陈拉斯2 天前
给公司年会写了个大屏抽奖系统:动画在前端跑,凭什么说结果没被改?
javascript
yzy852 天前
Vue中下载或打开文件的JavaScript方法
前端·javascript·vue
用户298698530142 天前
在 React 中用 JavaScript 将 Word 转换为文本
前端·javascript·react.js