[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
相关推荐
r0ad19 分钟前
读诗的时候我却使用了自己研发的Chrome元素截图插件
前端·javascript·chrome
知识分享小能手1 小时前
jQuery 入门学习教程,从入门到精通, jQuery在HTML5中的应用(16)
前端·javascript·学习·ui·jquery·html5·1024程序员节
七号练习生.c2 小时前
JavaScript基础入门
开发语言·javascript·ecmascript
baozj2 小时前
🚀 手动改 500 个文件?不存在的!我用 AST 撸了个 Vue 国际化神器
前端·javascript·vue.js
molly cheung3 小时前
FetchAPI 请求流式数据 基本用法
javascript·fetch·请求取消·流式·流式数据·流式请求取消
Mintopia3 小时前
🧠 量子计算对AIGC的潜在影响:Web技术的未来可能性
前端·javascript·aigc
忧郁的蛋~4 小时前
.NET异步编程中内存泄漏的终极解决方案
开发语言·前端·javascript·.net
水月wwww4 小时前
vue学习之组件与标签
前端·javascript·vue.js·学习·vue
顾安r4 小时前
11.8 脚本网页 塔防游戏
服务器·前端·javascript·游戏·html
在未来等你5 小时前
AI Agent设计模式 Day 3:Self-Ask模式:自我提问驱动的推理链
设计模式·llm·react·ai agent·plan-and-execute