首页 > 编程语言 >JavaScript高级程序设计的代理与捕获——工作中的实际意义。

JavaScript高级程序设计的代理与捕获——工作中的实际意义。

时间:2023-11-29 14:22:57浏览次数:30  
标签:实际意义 target 对象 JavaScript 代理 value set 程序设计 property

js红宝书写得很好,很多东西都给你一一解释了,但是有一点我很想吐槽:没有在写代码例子之前说明,相关东西有啥用,在实际工作中有啥现实意义等等,导致很多人理解了概念和看懂了枯燥的代码段后却无法有效运用到自己的工作当中。因为你不知道拿来用到什么地方或者说什么情况下才去用它!

举个我今天的例子,刚刚好复习到了js的代理与捕获,自己看完相关概念后觉得一脸懵,这东西拿来干啥的,我知道目标对象与代理之间的关系,也知道通过代理能影响到目标对象,但是不给我个具体例子的话,我是无法深入去理解和运用的。

因此,我就借助gpt-4了——问它能否为我解释一下js中的捕获与代理的定义并举出一个工作中的例子:

 gpt的回答:

在JavaScript中提到的“代理”(Proxy)与网络技术中的代理捕获器是不同的概念。JavaScript的代理是一个高级编程概念,它在日常编程中有着不同的用途和意义。在JavaScript中,代理(Proxy)指的是一个对象,它包裹另一个对象或函数,从而能够拦截并重新定义基本操作,比如属性读取、属性赋值、函数调用等。

JavaScript中的代理主要用于以下几个方面:

  1. 拦截和监控对象操作:你可以使用代理来监控对象的访问和修改,比如跟踪属性的读取和写入。

  2. 数据验证:代理可以用来在数据被写入对象之前进行验证,确保数据符合特定的规则。

  3. 实现高级编程模式:比如发布/订阅模式或虚拟化属性,代理可以帮助你创建更灵活和强大的代码结构。

  4. 延迟初始化:代理可以用于实现懒加载模式,即在实际需要前不初始化对象。

举个简单的例子,如果你有一个对象,你希望在每次修改其属性时都打印日志,你可以使用代理来实现这个功能。当该对象的属性被修改时,代理会自动触发一个函数,记录下这次操作。

那这样的例子解释就让我豁然开朗了,不用在那思考一会儿,浪费复习的时间,因为工具书就是工具书,就是要拿来实践的,所以我觉得如果能添加一个具体例子是在合理不过的了。

 

当然,我也有其他的疑问——为什么要代理另一个代理?

自己本身肯定理解它的定义了但是我想不到在那会用到它,因此就再次用到gpt4,以及它的回答是

在JavaScript中,对一个代理对象再进行代理,即在一个目标对象上构建多层拦截网,主要是为了实现更复杂或分层的拦截和处理逻辑。这种做法在某些场景中非常有用,尤其是在需要对对象的操作进行多级控制和管理时。

工作实际意义

  1. 分离关注点:不同层的代理可以处理不同的逻辑,比如一层处理日志记录,另一层处理数据验证,使代码更加模块化和可维护。

  2. 增强灵活性和可扩展性:通过多层代理,可以灵活地添加、修改或移除特定的拦截逻辑,而不影响其他层。

  3. 创建复杂的行为:在一些高级的编程场景中,比如设计模式的实现、框架开发等,多层代理可以创建复杂和强大的行为。

示例解释

假设你正在开发一个Web应用,其中有一个用户对象,你需要对这个对象进行以下处理:

  • 日志记录:追踪对象属性的变更。
  • 验证:确保用户的年龄和邮箱格式是正确的。

为了分离这些关注点,你可以创建两层代理:

  1. 第一层代理负责日志记录。每当对象的属性被访问或修改时,这层代理记录下相关信息。

  2. 第二层代理负责数据验证。当尝试设置对象的年龄或邮箱时,这层代理验证数据是否符合预定的规则。

通过这样的设计,你可以独立地修改日志记录或验证逻辑,而不会影响到另一层。同时,如果将来需要添加新的拦截逻辑,比如权限检查,你只需要添加另一层代理即可。

代码如下:

let user = {
    name: "Alice",
    age: 25,
    email: "[email protected]"
};

let loggerProxy = new Proxy(user, {
    get(target, property) {
        console.log(`Property ${property} has been read`);
        return target[property];
    },
    set(target, property, value) {
        console.log(`Property ${property} is set to ${value}`);
        target[property] = value;
        return true;
    }
});

let validationProxy = new Proxy(loggerProxy, {
    set(target, property, value) {
        if (property === 'age' && (typeof value !== 'number' || value < 0)) {
            throw new Error("Invalid age");
        }
        if (property === 'email' && !/\S+@\S+\.\S+/.test(value)) {
            throw new Error("Invalid email");
        }
        return Reflect.set(target, property, value);
    }
});

// 使用 validationProxy 作为用户对象的操作接口
validationProxy.age = 30;  // 日志记录,然后验证年龄
validationProxy.email = "[email protected]";  // 日志记录,然后验证邮箱格式

通过这样的解释和举例,我就懂得了在工作当中遇到哪些情况才会用到它,而不是看完就扔,等项目出bug后再去查看和重新学习它是个啥意思...

当然,代理也不是万能的,总有缺点的时候,例如书中就提到了代理中的this和代理与内部槽位的问题:

const wm = new WeakMap(); 
class User { 
 constructor(userId) { 
 wm.set(this, userId); 
 } 
 set id(userId) { 
 wm.set(this, userId); 
 } 
 get id() { 
 return wm.get(this); 
 } 
} 

这个代理中的this,我们打印出来后会发现,它只会到代理自身的实例而不是调用这个方法的函数本身。

关于内部槽位与代理,主要Date()的问题:

const target = new Date(); 
const proxy = new Proxy(target, {}); 
console.log(proxy instanceof Date); // true 
proxy.getDate(); // TypeError: 'this' is not a Date object

书中的原话:一个典型的例子就是 Date 类型。根据 ECMAScript 规范,Date 类型方法的执行依赖 this 值上的 内部槽位[[NumberDate]]。代理对象上不存在这个内部槽位,而且这个内部槽位的值也不能通过普通 的 get()和 set()操作访问到,于是代理拦截后本应转发给目标对象的方法会抛出 TypeError。

好了这就是我今天的记录,大家真的要学会多利用ai来帮助自己去学习或者更深入去理解相关知识。

 

 

 

 

 

 

 

标签:实际意义,target,对象,JavaScript,代理,value,set,程序设计,property
From: https://www.cnblogs.com/katyjohn/p/17864690.html

相关文章

  • JavaScript编码风格指南
    sidebar:autosidebarDepth:4JavaScript编码风格指南内容出处:NicholasC.Zakas《编写可维护的JavaScript》GoogleJavaScriptStyleGuidecrockfordJSLintESLint好狗电影导航源文件基础命名文件名必须全部小写,并且可以包含下划线(_)或短划线(-),但不包含......
  • C++20高级编程 第五章 面向对象程序设计
    第五章面向对象设计面向过程思想众所周知的,C语言是一门面向过程编程的语言,而C++是一门半面向对象编程(ObjectOrientedProgramming,OOP)的语言.面向过程编程的语言通常将代码分割成小块,每个小块理论上完成单一的任务.如果在C程序中没有过程,所有代码都会集中于main()......
  • vue3+vite 代码混淆插件 | JavaScript obfuscator
    安装插件yarnadd--devrollup-plugin-javascript-obfuscator创建obfuscator.js文件,把下面相应代码放入js文件中importobfuscatorPluginfrom'rollup-plugin-javascript-obfuscator';exportfunctioncodeObfuscatorPlugin(isBuild){if(!isBuild){return[];}......
  • JavaScript 的基本规范
    在平常项目开发中,我们遵守一些这样的基本规范,比如说:(1)一个函数作用域中所有的变量声明应该尽量提到函数首部,用一个var声明,不允许出现两个连续的var声明,声明时  如果变量没有值,应该给该变量赋值对应类型的初始值,便于他人阅读代码时,能够一目了然的知道变量对应的类型值。(2)......
  • 高级语言程序设计(C语言)
    第一章.计算机的发展世界上第一台计算机1946年美国:ENIAC电子数字积分计算机电子管为主要元件,冯.诺依曼提出存储程序概念和二进制思想;1.四个发展时代1>第一代:20世纪50年代,主要采用真空电子管制造计算机2>第二代:20世纪50年代末期:出现了以晶体管为主要元件的第二代......
  • JavaScript
    JavaScript是一种高级解释性脚本语言,已得到广泛使用,是Web开发的重要工具。它由NetscapeCommunicationsCorporation、Mozilla基金会和ECMAInternational开发。它易于学习和实施,并允许开发人员增强网页以提供身临其境的用户体验。JavaScript入门非常简单,您只需要一个用......
  • 基于WSAAsyncSelect模型的通信程序设计
    基于WSAAsyncSelect模型的通信程序设计一、问题描述编写Win32程序模拟实现基于WSAAsyncSelect模型的两台计算机之间的通信,要求编程实现服务器端与客户端之间双向数据传递。客户端向服务器端发送“请输出从1到1000内所有的质数”,服务器回应客户端给出结果。二、代码实现①CInit......
  • Typescript和Javascript的区别是什么?一文带您了解Typescript排名飙升的原因!
    看见了github上2023年编程语言的排行榜,Java竟然被typescript挤出了前三!Javascript的登顶得益于node.js 的出现,使js实现了在前后端的技术栈统一。那typescript为何又能在三足鼎立中占据一席之地呢?本文就对typescript进行一下概要介绍,本文并未涉及typescript的具体语法,注重分析Javas......
  • 2023-2024-1 20231309 《计算机基础与程序设计》第九周学习总结
    2023-2024-120231309《计算机基础与程序设计》第八周学习总结作业信息这个作业属于哪个课程2023-2024-1-计算机基础与程序设计这个作业要求在哪里2023-2024-1计算机基础与程序设计第九周作业这个作业的目标作业正文2023-2024-120231309《计算机基础与程......
  • 2023-2024-1 20231415 《计算机基础与程序设计》第九周学习总结
    这个作业属于哪个课程 这个作业要求在哪里 作业目标 作业正文 教材内容总结《计算机科学概论》第十章操作系统操作系统的角色与构成进程管理先到先服务FCFS最短作业优先轮询法内存管理单块内存管理分区内存管理页式内存管理CPU调用先到先服务FCFS最短作......