JavaScript代理是什么?javascript代理的介绍
本篇文章给大家带来的内容是关于JavaScript代理是什么?javascript代理的介绍,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
前言
什么是代理?
上小学的时候,李小红来你家叫你出去玩,第一个回应的不是你自己,是你妈:“王小明在家写作业,今天不出去!”
上中学的时候,赵二虎带着小弟们放学在校门口等着揍你,走在前面的不是你自己,是二虎他爸:“考试没及格还学会装黑社会了!”拎起二虎就是一顿胖揍。
上了大学,躺在宿舍里的床上,好饿。出门买饭并交代好不要葱蒜多放辣最后还直接端到床上的不是你自己,是快递小哥。
这些都是代理。
什么是 JavaScript 代理?
用官方的洋文来说,是 Proxy:
The Proxy object is used to define custom behavior for fundamental operations (e.g. property lookup, assignment, enumeration, function invocation, etc).
通过 Proxy 我们可以拦截并改变一个对象的几乎所有的根本操作,包括但不限于属性查找、赋值、枚举、函数调用等等。
在生活中,通过代理我们可以自动屏蔽小红的邀请、自动赶走二虎的威胁、自动买好干净的饭端到床上。在 JavaScript 世界里,代理也可以帮你做类似的事情,接下来让我们一起琢磨一番。
初识代理:Hello World
以小学经历为例子,心里是喜欢小红的,于是我们定义:
const me = { name: '小明', like: '小红' }
这个时候如果调用 console.log(me.like)
,结果必然是 小红
。然而生活并不是这样,作为一个未成年人,总是有各种的代理人围绕在你身边,比如这样:
const meWithProxy = new Proxy(me, { get(target, prop) { if (prop === 'like') { return '学习'; } return target[prop]; } });
这个时候如果调用 console.log(me.like)
依然是 小红
,因为真心不会说谎。但当我们调用 console.log(meWithProxy.like)
的时候,就会可耻的输出 学习
,告诉大家说我们喜欢的是 学习
。
小试牛刀:不要停止我的音乐
刚才我们简单了解了代理能够拦截对象属性的获取,可以隐藏真实的属性值而返回代理想要返回的结果,那么对于对象属性的赋值呢?让我们一起来看看。
假设你正在听音乐:
const me = { name: '小明', musicPlaying: true }
此时如果我们执行 me.musicPlaying = false
这样就轻而易举地停止了你的音乐,那么如果我们挂上代理人:
const meWithProxy = new Proxy(me, { set(target, prop, value) { if (prop === 'musicPlaying' && value !== true) { throw Error('任何妄图停止音乐的行为都是耍流氓!'); } target[prop] = value; } });
这时候如果我们执行 me.musicPlaying = false
,就会被毫不留情地掀了桌子:
> meWithProxy.musicPlaying = false Error: 任何妄图停止音乐的行为都是耍流氓! at Object.set (repl:4:13) >
释放魔法:封装全宇宙所有 RESTful API
现在我们已经知道通过 Proxy 可以拦截属性的读写操作,那然后呢?没什么用?
仅仅是拦截属性的读写操作,的确没有太大的发挥空间,或许可以方便的做一些属性赋值校验工作等等。但是,或许你还没有意识到一个惊人的秘密:Proxy 在拦截属性读写操作时,并不在乎属性是否真的存在!
那么,也就是说:利用 Proxy,我们可以拦截并不存在的属性的读取。
再进一步思考:利用 Proxy,我们可以在属性读取的那一瞬间,动态构造返回结果。
然而,属性并不局限于字符串、布尔值,属性可以是对象、函数、任何东西。
至此,你想到了什么?
没想到?不要紧!根据刚才的分析,让我们一起通过下面 17 行代码,来封装全宇宙所有的 RESTful API !
import axios from 'axios'; const api = new Proxy({}, { get(target, prop) { const method = /^[a-z]+/.exec(prop)[0]; const path = '/' + prop .substring(method.length) .replace(/([a-z])([A-Z])/g, '$1/$2') .replace(/\$/g, '/$/') .toLowerCase(); return (...args) => { // <------ 返回动态构造的函数! const url = path.replace(/\$/g, () => args.shift()); const options = args.shift() || {}; console.log('Requesting: ', method, url, options); return axios({ method, url, ...options }); } } });
定义了 api 这个代理之后,我们就可以像下面这样调用:
api.get() // GET / api.getUsers() // 获取所有用户 // GET /users api.getUsers$Books(42) // 获取 ID 为 42 的用户的所有书籍 // GET /users/42/books api.getUsers$Books(42, { params: { page: 2 } }) // 获取 ID 为 42 的用户的所有书籍的第二页 // GET /users/42/books?page=2 api.postUsers({ data: { name: '小明' } }) // 创建名字为 小明 的用户 // POST /users Payload { name: '小明' }
以上所有的函数都在你调用的那一瞬间,通过代理人的魔法之手动态生成,供我们随意取用。
简洁、优雅,哇~ 真是太棒啦!
终极魔幻:通读代理人的魔法秘笈
到此,我们仅仅使用 Proxy 改造了对象的属性获取、赋值操作,而对于 Proxy 来说,只是冰山一角。
Proxy 的基本语法如下:
new Proxy(target, handler)
其中 target
是即将被代理的对象(比如:想要出门找小红玩耍的 me
),handler
就是代理的魔法之手,用来拦截、改造 target
的行为。
对于 handler
对象,我们刚才仅仅用到了 get
、set
函数,而实际上一共有 13 种可代理的操作:
-
handler.getPrototypeOf()
在读取代理对象的原型时触发该操作,比如在执行 Object.getPrototypeOf(proxy) 时。
-
handler.setPrototypeOf()
在设置代理对象的原型时触发该操作,比如在执行 Object.setPrototypeOf(proxy, null) 时。
-
handler.isExtensible()
在判断一个代理对象是否是可扩展时触发该操作,比如在执行 Object.isExtensible(proxy) 时。
-
handler.preventExtensions()
在让一个代理对象不可扩展时触发该操作,比如在执行 Object.preventExtensions(proxy) 时。
-
handler.getOwnPropertyDescriptor()
在获取代理对象某个属性的属性描述时触发该操作,比如在执行 Object.getOwnPropertyDescriptor(proxy, "foo") 时。
-
handler.defineProperty()
在定义代理对象某个属性时的属性描述时触发该操作,比如在执行 Object.defineProperty(proxy, "foo", {}) 时。
-
handler.has()
在判断代理对象是否拥有某个属性时触发该操作,比如在执行 "foo" in proxy 时。
-
handler.get()
在读取代理对象的某个属性时触发该操作,比如在执行 proxy.foo 时。
-
handler.set()
在给代理对象的某个属性赋值时触发该操作,比如在执行 proxy.foo = 1 时。
-
handler.deleteProperty()
在删除代理对象的某个属性时触发该操作,比如在执行 delete proxy.foo 时。
-
handler.ownKeys()
在获取代理对象的所有属性键时触发该操作,比如在执行 Object.getOwnPropertyNames(proxy) 时。
-
handler.apply()
在调用一个目标对象为函数的代理对象时触发该操作,比如在执行 proxy() 时。
-
handler.construct()
在给一个目标对象为构造函数的代理对象构造实例时触发该操作,比如在执行new proxy() 时。
对于以上 13 种可代理的操作,还需要读者自行研究并实践方可踏上终极魔幻之旅。
以上是JavaScript代理是什么?javascript代理的介绍的详细内容。更多信息请关注PHP中文网其他相关文章!

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

热门话题

PHP与Vue:完美搭档的前端开发利器在当今互联网高速发展的时代,前端开发变得愈发重要。随着用户对网站和应用的体验要求越来越高,前端开发人员需要使用更加高效和灵活的工具来创建响应式和交互式的界面。PHP和Vue.js作为前端开发领域的两个重要技术,搭配起来可以称得上是完美的利器。本文将探讨PHP和Vue的结合,以及详细的代码示例,帮助读者更好地理解和应用这两

本站4月17日消息,集邦咨询(TrendForce)近日发布报告,认为英伟达Blackwell新平台产品需求看涨,预估带动台积电2024年CoWoS封装总产能提升逾150%。英伟达Blackwell新平台产品包括B系列的GPU,以及整合英伟达自家GraceArmCPU的GB200加速卡等。集邦咨询确认为供应链当前非常看好GB200,预估2025年出货量有望超过百万片,在英伟达高端GPU中的占比达到40-50%。在英伟达计划下半年交付GB200以及B100等产品,但上游晶圆封装方面须进一步采用更复

在前端开发面试中,常见问题涵盖广泛,包括HTML/CSS基础、JavaScript基础、框架和库、项目经验、算法和数据结构、性能优化、跨域请求、前端工程化、设计模式以及新技术和趋势。面试官的问题旨在评估候选人的技术技能、项目经验以及对行业趋势的理解。因此,应试者应充分准备这些方面,以展现自己的能力和专业知识。

本站7月9日消息,AMDZen5架构“Strix”系列处理器会有两种封装方案,其中较小的StrixPoint将采用FP8封装,而StrixHalo将会采用FP11封装。图源:videocardz消息源@Olrak29_最新曝料称StrixHalo的FP11封装尺寸为37.5mm*45mm(1687平方毫米),和英特尔AlderLake、RaptorLakeCPU的LGA-1700封装尺寸相同。AMD最新的PhoenixAPU采用FP8封装方案,尺寸为25*40mm,这意味着StrixHalo的F

Oracle是一家全球知名的数据库管理系统提供商,其API(ApplicationProgrammingInterface,应用程序接口)是一种强大的工具,可帮助开发人员轻松地与Oracle数据库进行交互和集成。在本文中,我们将深入探讨OracleAPI的使用指南,向读者展示如何在开发过程中利用数据接口技术,同时提供具体的代码示例。1.Oracle

标题:如何处理LaravelAPI报错问题,需要具体代码示例在进行Laravel开发时,经常会遇到API报错的情况。这些报错可能来自于程序代码逻辑错误、数据库查询问题或是外部API请求失败等多种原因。如何处理这些报错是一个关键的问题,本文将通过具体的代码示例来演示如何有效处理LaravelAPI报错问题。1.错误处理在Laravel

OracleAPI集成策略解析:实现系统间无缝通信,需要具体代码示例在当今数字化时代,企业内部系统之间需要相互通信和数据共享,而OracleAPI就是帮助实现系统间无缝通信的重要工具之一。本文将从OracleAPI的基本概念和原理入手,探讨API集成的策略,最终给出具体的代码示例帮助读者更好地理解和应用OracleAPI。一、OracleAPI基本

Go语言作为一种快速、高效的编程语言,在后端开发领域广受欢迎。然而,很少有人将Go语言与前端开发联系起来。事实上,使用Go语言进行前端开发不仅可以提高效率,还能为开发者带来全新的视野。本文将探讨使用Go语言进行前端开发的可能性,并提供具体的代码示例,帮助读者更好地了解这一领域。在传统的前端开发中,通常会使用JavaScript、HTML和CSS来构建用户界面
