Menschen, die Autos fahren, verstehen die Struktur des Autos oft nicht, aber ein tiefes Verständnis der Struktur des Autos kann noch aussagekräftiger sein
Da die Nachrichten über vue3.x
zunehmen, nimmt auch die Diskussion über proxy
zu. Was sind die Unterschiede, Vorteile und Anwendungen von Object.defineProperty
im Vergleich zu proxy
? In diesem Artikel wird
kurz vorgestellt. Bevor wir über proxy
sprechen, werfen wir zunächst einen Blick auf Object.defineProperty
. Wie wir alle wissen, verwenden vue2.x
und frühere Versionen Object.defineProperty
, um eine bidirektionale Bindung von Daten zu erreichen. Lassen Sie uns einfach
function observer(obj) { if (typeof obj === 'object') { for (let key in obj) { defineReactive(obj, key, obj[key]) } } } function defineReactive(obj, key, value) { //针对value是对象,递归检测 observer(value) //劫持对象的key Object.defineProperty(obj, key, { get() { console.log('获取:' + key) return value }, set(val) { //针对所设置的val是对象 observer(val) console.log(key + "-数据改变了") value = val } }) } let obj = { name: '守候', flag: { book: { name: 'js', page: 325 }, interest: ['火锅', '旅游'], } } observer(obj)
implementieren und im console
des Browsers ausführen. Es scheint normal zu laufen
Aber tatsächlich hat Object.defineProperty
das folgende Probleme Mehrere
Fragen 1. Das Löschen oder Hinzufügen von Objektattributen kann nicht überwacht werden
Zum Beispiel das Hinzufügen eines Attributs gender
, da beim Ausführen von observer(obj)
kein solches Attribut vorhanden ist, also dies nicht überwacht werden kann. Gelöschte Attribute können nicht überwacht werden. Wenn
Attribute hinzufügt, muss
vue
zum Betrieb$set
verwenden, und$set
verwendet auchObject.defineProperty
zum Betrieb innerhalb von
Problem 2. Änderungen im Array können nicht überwacht werden
Wie aus dem obigen Bild ersichtlich ist, obwohl die Array-Attribute dies sind tatsächlich erfolgreich geändert, kann aber nicht überwacht werden
Frage 3.
Da das Objekt rekursiv durchlaufen wird, wird Object.defineProperty
verwendet, um die Eigenschaften des Objekts zu kapern. Wenn die durchquerte Objektebene tief ist, dauert es lange und es kann sogar zu Leistungsproblemen kommen
Für proxy
lautet die Beschreibung auf mdn: Das Objekt wird verwendet, um benutzerdefiniertes Verhalten für grundlegende Vorgänge zu definieren (z. B. Attributsuche, Zuweisung, Aufzählung, Funktionsaufruf usw.)
Um es einfach auszudrücken: Sie können eine Abfangebene für das Zielobjekt einrichten. Unabhängig davon, welche Operation am Zielobjekt ausgeführt wird, muss es diese Abfangebene durchlaufen
Es hört sich so an, als wäre proxy
einfacher zu verwenden als Object.defineProperty
und viel einfacher, und das ist tatsächlich der Fall . Lassen Sie uns den obigen Code mithilfe eines Proxys neu schreiben und versuchen, mit
function observerProxy(obj) { let handler = { get(target, key, receiver) { console.log('获取:' + key) // 如果是对象,就递归添加 proxy 拦截 if (typeof target[key] === 'object' && target[key] !== null) { return new Proxy(target[key], handler) } return Reflect.get(target, key, receiver) }, set(target, key, value, receiver) { console.log(key + "-数据改变了") return Reflect.set(target, key, value, receiver) } } return new Proxy(obj, handler) } let obj = { name: '守候', flag: { book: { name: 'js', page: 325 }, interest: ['火锅', '旅游'], } } let objTest = observerProxy(obj)
den gleichen Effekt zu erzielen.
Darüber hinaus kann es Dinge tun, die Object.defineProperty
nicht möglich sind Wenn Sie beispielsweise ein Attribut gender
hinzufügen, können Sie das Operationsarray
und auch
Klopfen Sie zuletzt an die Tafel und fassen Sie kurz die Unterschiede zwischen den beiden zusammen 1. Was abgefangen wird, ist das Attribut des Objekts, das das ursprüngliche Objekt verändert. Object.defineProperty
fängt das gesamte Objekt ab und generiert durch new ein neues Objekt, ohne das ursprüngliche Objekt zu ändern. proxy
. Es gibt viele Möglichkeiten zur Auswahl. Proxy kann auch einige Vorgänge überwachen, die nicht von proxy
überwacht werden können, z. B. das Überwachen von Arrays, das Überwachen des Hinzufügens und Löschens von Objektattributen usw. Object.defineProperty
werde ich hier aus Platzgründen einfach einige auflisten, weitere finden Sie auf meiner Seite Github Notes oder MDN. proxy
. Aber in welchen Szenarien kann proxy
in der Entwicklung verwendet werden? Hier sind einige Situationen, die auftreten können: proxy
, splice(-1)
Wenn bei Verwendung der API eine negative Zahl eingegeben wird, wird das letzte Element des Arrays positioniert. Negative Zahlen können jedoch nicht in normalen Arrays verwendet werden. slice(-1)
Dieser Code gibt nicht 3 aus. Um die obige Codeausgabe 3 zu erstellen, können Sie auch [1,2,3][-1]
verwenden, um dies zu erreichen. proxy
<br>
在对表单的值进行改动的时候,可以在 set
里面进行拦截,判断值是否合法
let ecValidate = { set(target, key, value, receiver) { if (key === 'age') { //如果值小于0,或者不是正整数 if (value < 0 || !Number.isInteger(value)) { throw new TypeError('请输入正确的年龄'); } } return Reflect.set(target, key, value, receiver) } } let obj = new Proxy({ age: 18 }, ecValidate) obj.age = 16obj.age = '少年'
比如有一个需求,保证用户输入正确身份证号码之后,把出生年月,籍贯,性别都添加进用户信息里面
众所周知,身份证号码第一和第二位代表所在省(自治区,直辖市,特别行政区),第三和第四位代表所在市(地级市、自治州、盟及国家直辖市所属市辖区和县的汇总码)。第七至第十四位是出生年月日。低17位代表性别,男单女双。
const PROVINCE_NUMBER = { 44 : '广东省', 46 : '海南省' } const CITY_NUMBER = { 4401 : '广州市', 4601 : '海口市' } let ecCardNumber = { set(target, key, value, receiver) { if (key === 'cardNumber') { Reflect.set(target, 'hometown', PROVINCE_NUMBER[value.substr(0, 2)] + CITY_NUMBER[value.substr(0, 4)], receiver) Reflect.set(target, 'date', value.substr(6, 8), receiver) Reflect.set(target, 'gender', value.substr( - 2, 1) % 2 === 1 ? '男': '女', receiver) } return Reflect.set(target, key, value, receiver) } } let obj = new Proxy({ cardNumber: '' }, ecCardNumber)
比如有一个需求,需要传时间戳给到后端,但是前端拿到的是一个时间字符串,这个也可以用 proxy
进行拦截,当得到时间字符串之后,可以自动加上时间戳。
let ecArrayProxy = { get(target, key, receiver) { let _index = key < 0 ? target.length + Number(key) : key return Reflect.get(target, _index, receiver) } } let arr = new Proxy([1, 2, 3], ecArrayProxy)
<br>
推荐教程:《JS教程》 <br>
Das obige ist der detaillierte Inhalt vonVorteile und Einsatzszenarien von JS Proxy. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!