JS设计模式 — 行为委托

news/2024/2/29 17:55:40 标签: javascript, 设计模式, 原型模式

回顾一下原型,发现[[Prototype]]机制就是指对象中的一个内部链接引用另一个对象,这个机制的本质就是对象之间的关联关系

1、面相委托的设计

Task = {
	setID: function(ID) { this.id = ID; },
	outputID: function() { console.log( this.id ); }
};
// 让 XYZ 委托 Task
XYZ = Object.create( Task );
XYZ.prepareTask = function(ID,Label) {
	this.setID( ID );
	this.label = Label;
};
XYZ.outputTaskDetails = function() {
	this.outputID();
	console.log( this.label );
};
// ABC = Object.create( Task );
// ABC ... = ...

我们把这种编码风格称为“对象关联”,在JS中[[Prototype]]机制会把对象关联到其他对象,对象关联的代码会有一些不同之处:

  1. 在上面的代码中,id 和 label 数据成员都是直接存储在 XYZ 上(而不是 Task)。通常来说,在 [[Prototype]] 委托中最好把状态保存在委托者(XYZ、ABC)而不是委托目标(Task)上。

  2. 在类设计模式中,我们故意让父类(Task)和子类(XYZ)中都有 outputTask 方法,这
    样就可以利用重写(多态)的优势。在委托行为中则恰好相反:我们会尽量避免在[[Prototype]] 链的不同级别中使用相同的命名,否则就需要使用笨拙并且脆弱的语法来消除引用歧义(参见第 4 章)。
    这个设计模式要求尽量少使用容易被重写的通用方法名,提倡使用更有描述性的方法名,尤其是要写清相应对象行为的类型。这样做实际上可以创建出更容易理解和维护的代码,因为方法名(不仅在定义的位置,而是贯穿整个代码)更加清晰(自文档)。

  3. this.setID(ID);XYZ 中的方法首先会寻找 XYZ 自身是否有 setID(…),但是 XYZ 中并没有这个方法名,因此会通过 [[Prototype]] 委托关联到 Task 继续寻找,这时就可以找到setID(…) 方法。此外,由于调用位置触发了 this 的隐式绑定规则(参见第 2 章),因此虽然 setID(…) 方法在 Task 中,运行时 this 仍然会绑定到 XYZ,这正是我们想要的。在之后的代码中我们还会看到 this.outputID(),原理相同。

    换句话说,我们和 XYZ 进行交互时可以使用 Task 中的通用方法,因为 XYZ 委托了 Task。

委托行为意味着某些对象(XYZ)在找不到属性或者方法引用时会把这个请求委托给另一个对象(Task)。这是一种极其强大的设计模式,和父类、子类、继承、多态等概念完全不同

2、总结

在软件架构中你可以选择是否使用类和继承设计模式。大多数开发者理所当然地认为类是唯一(合适)的代码组织方式,但是本章中我们看到了另一种更少见但是更强大的设计模式:行为委托。

行为委托认为对象之间是兄弟关系,互相委托,而不是父类和子类的关系。JavaScript 的[[Prototype]] 机制本质上就是行为委托机制。也就是说,我们可以选择在 JavaScript 中努力实现类机制,也可以拥抱更自然的 [[Prototype]] 委托机制。

当你只用对象来设计代码时,不仅可以让语法更加简洁,而且可以让代码结构更加清晰。

对象关联(对象之前互相关联)是一种编码风格,它倡导的是直接创建和关联对象,不把它们抽象成类。对象关联可以用基于 [[Prototype]] 的行为委托非常自然地实现。


http://www.niftyadmin.cn/n/5228876.html

相关文章

Vue3中快速Diff算法

在Vue3中,快速Diff算法主要用于优化虚拟DOM的更新过程,减少不必要的DOM操作,提高性能。以下是对Vue3源码中快速Diff算法的解读: 首先,我们需要引入Vue3的相关包: import { reactive, toRefs, watch } fro…

C语言--每日选择题--Day31

第一题 1. 下面程序 i 的值为() int main() {int i 10;int j 0;if (j 0)i; elsei--; return 0; } A:11 B:9 答案及解析 B if语句中的条件判断为赋值语句的时候,因为赋值语句的返回值是右操作数; …

Cookie要怎么测试?

前言 Cookie是一种用于在web应用程序中存储用户特定信息的方法,可以让网站服务器把少量数据存储到客户端的硬盘或内存,或是从客户端的硬盘读取数据。Cookie的测试是指对Cookie的功能、性能、安全性、兼容性等方面进行验证的过程。 同时,在这…

鸿蒙系统开发手册 - HarmonyOS内核驱动层源码分析

众所周知系统定义HarmonyOS是一款“面向未来”、面向全场景(移动办公、运动健康、社交通信、媒体娱乐等)的分布式操作系统。在传统的单设备系统能力的基础上,HarmonyOS提出了基于同一套系统能力、适配多种终端形态的分布式理念,能…

图解系列--HTTPS,认证

确保 Web 安全的HTTPS 1.HTTP 的缺点 1.1.通信使用明文可能会被窃听 加密处理防止被窃听 加密的对象可以有这么几个。 (1).通信的加密 HTTP 协议中没有加密机制,但可以通过和 SSL(Secure Socket Layer,安全套接层)或TLS&#xff…

FASTJSON v2详解

FASTJSON 2是一个性能极致并且简单易用的Java JSON库。 FASTJSON 2是FASTJSON项目的重要升级,和FASTJSON 1相比,性能有非常大的提升,解决了autoType功能因为兼容和白名单的安全性问题。 性能极致,性能远超过其他流行JSON库&#x…

windows文件删除权限

一、普通文件 这里指的是所有可以被随意删除的文件。 二、可更改权限的文件 如果想要删除的文件无法被删除,那大概是权限不够,这时候:鼠标右键、属性、安全、编辑、选择相应的组或用户(如果不知道哪个可以全选,反正…

【Openstack Train安装】二、NTP安装

网络时间协议:Network Time Protocol(NTP)是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精准度的时间校正(LAN上与…

ArkUI框架中的PersistentStorage和Environment深入详解【鸿蒙专栏-13】

文章目录 ArkUI框架中的PersistentStorage和EnvironmentPersistentStorage:保持状态的长存储概述限制条件使用场景初始化和访问属性示例流程图注意事项Environment:设备环境查询使用场景从UI中访问Environment参数应用逻辑使用Environment深入ArkUI框架的持久化存储与设备环境…

MySQL之redo log

聊聊REDO LOG 为什么需要redolog? 那redolog主要是为了保证数据的持久化,我们知道innodb存储引擎中数据是以页为单位进行存储,每一个页中有很多行记录来存储数据,我们的数据最终是要持久化到硬盘中,那如果我们每进行…

mvn 编译时报错 java heap space

问题描述 使用IDEA进行war打包时,编译类都正常,但是最后生成 war 包时很慢,有些时候还会报错: java head space。具体错误如图: 问题诊断 换电脑,可行清理 .idea 目录重新打包还是不行升级 maven-war-plu…

智能优化算法应用:基于旗鱼算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于旗鱼算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于旗鱼算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.旗鱼算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

解决:ValueError: the first two maketrans arguments must have equal length

解决:ValueError: the first two maketrans arguments must have equal length 文章目录 解决:ValueError: the first two maketrans arguments must have equal length背景报错问题报错翻译报错位置代码报错原因解决方法今天的分享就到此结束了 背景 在…

Elk+Filebeat+Kafka实现日志收集

ElkFilebeatKafka实现日志收集(本机nginx) 部署Zookeeper 1.实验组件 #准备3台服务器做Zookeeper集群 20.0.0.10 20.0.0.20 20.0.0.30 2.安装前准备 #关闭防火墙 systemctl stop firewalld systemctl disable firewalld setenforce 0#安装JDK yum install -y java-1.8.0-o…

Element UI之Dialog 对话框

Dialog 对话框 用于弹出窗口 按需引入方式 如果是完整引入可跳过此步骤 import Vue from vue import { Dialog } from element-ui import element-ui/lib/theme-chalk/base.css import element-ui/lib/theme-chalk/dialog.cssVue.use(Dialog)基础使用 <template><…

序列化-Serializable和Parcelable

Serializable 在Android开发中&#xff0c;Serializable是一种用于将对象序列化和反序列化的接口。它是Java的标准序列化方式&#xff0c;可以在任何Java平台上使用。 下面是使用Serializable进行对象序列化的步骤&#xff1a; 在要序列化的类中实现Serializable接口&#x…
最新文章