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脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

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

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

本站4月17日消息,集邦諮詢(TrendForce)近日發布報告,認為英偉達Blackwell新平台產品需求看漲,預估帶動台積電2024年CoWoS封裝總產能提升逾150%。英偉達Blackwell新平台產品包含B系列的GPU,以及整合英偉達自家GraceArmCPU的GB200加速卡等。集邦諮詢確認為供應鏈目前非常看好GB200,預估2025年出貨量預計超過百萬片,在英偉達高階GPU中的佔比達到40-50%。在英偉達計畫下半年交付GB200以及B100等產品,但上游晶圓封裝方面須進一步採用更複

PHP與Vue:完美搭檔的前端開發利器在當今網路快速發展的時代,前端開發變得愈發重要。隨著使用者對網站和應用的體驗要求越來越高,前端開發人員需要使用更有效率和靈活的工具來創建響應式和互動式的介面。 PHP和Vue.js作為前端開發領域的兩個重要技術,搭配起來可以稱得上是完美的利器。本文將探討PHP和Vue的結合,以及詳細的程式碼範例,幫助讀者更好地理解和應用這兩

Oracle是一家全球知名的資料庫管理系統供應商,其API(ApplicationProgrammingInterface,應用程式介面)是一種強大的工具,可協助開發人員輕鬆地與Oracle資料庫互動和整合。在本文中,我們將深入探討OracleAPI的使用指南,向讀者展示如何在開發過程中利用資料介面技術,同時提供具體的程式碼範例。 1.Oracle

OracleAPI整合策略解析:實現系統間無縫通信,需要具體程式碼範例在當今數位化時代,企業內部系統之間需要相互通信和資料共享,而OracleAPI就是幫助實現系統間無縫通信的重要工具之一。本文將從OracleAPI的基本概念和原則入手,探討API整合的策略,最終給出具體的程式碼範例幫助讀者更好地理解和應用OracleAPI。一、OracleAPI基本

標題:如何處理LaravelAPI報錯問題,需要具體程式碼範例在進行Laravel開發時,常會遇到API報錯的情況。這些報錯可能來自於程式碼邏輯錯誤、資料庫查詢問題或是外部API請求失敗等多種原因。如何處理這些報錯是一個關鍵的問題,本文將透過具體的程式碼範例來示範如何有效處理LaravelAPI報錯問題。 1.錯誤處理在Laravel

Go語言作為一種快速、高效的程式語言,在後端開發領域廣受歡迎。然而,很少有人將Go語言與前端開發聯繫起來。事實上,使用Go語言進行前端開發不僅可以提高效率,還能為開發者帶來全新的視野。本文將探討使用Go語言進行前端開發的可能性,並提供具體的程式碼範例,幫助讀者更了解這一領域。在傳統的前端開發中,通常會使用JavaScript、HTML和CSS來建立使用者介面

本站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

透過封裝程式碼,C++函數可以提高GUI開發效率:程式碼封裝:函數將程式碼分組到獨立單元,使程式碼易於理解和維護。可重複使用性:函數可建立通用功能供應用程式中重複使用,減少重複編寫和錯誤。簡潔程式碼:封裝程式碼讓主邏輯簡潔,方便閱讀和除錯。
