Heim  >  Artikel  >  Web-Frontend  >  Ein Artikel, der die Verwendung von ES6-Proxy-Proxy in JS (Code-Sharing) erläutert.

Ein Artikel, der die Verwendung von ES6-Proxy-Proxy in JS (Code-Sharing) erläutert.

奋力向前
奋力向前nach vorne
2021-08-27 10:23:331965Durchsuche

Im vorherigen Artikel „Eine kurze Analyse der Optimierung von Web-Front-End-Projekten in Vue (mit Code)“ haben wir etwas über die Optimierung von Web-Front-End-Projekten in Vue erfahren. Der folgende Artikel führt Sie in die Verwendung des ES6-Proxy-Proxys in JS ein.

Ein Artikel, der die Verwendung von ES6-Proxy-Proxy in JS (Code-Sharing) erläutert.

Das Konzept von Proxy

proxyDie ursprüngliche englische Bedeutung ist Proxy. In ES6 kann es als „Agent“ übersetzt werden. Es wird hauptsächlich verwendet, um das Standardverhalten bestimmter Vorgänge zu ändern, was einer Änderung auf Sprachebene entspricht. Es handelt sich also um eine Art „Meta-Programmierung“ (meta programming), also Programmierung eine Programmiersprache. proxy英文原意是代理的意思,在ES6中,可以翻译为"代理器"。它主要用于改变某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程。

proxy在目标对象的外层搭建了一层拦截,外界对目标对象的某些操作(后文会说明,有哪些操作可以拦截),必须通过这层拦截。语法

var proxy = new Proxy(target, handler);

通过构造函数生成proxytarget参数是要拦截的目标对象,handler参数也是一个对象,用来定制拦截行为。

例子

var obj = new Proxy(
  {},
  {
    get: function (target, key, receiver) {
      console.log(`getting ${key}!`);
      return Reflect.get(target, key, receiver);
    },
    set: function (target, key, value, receiver) {
      console.log(`setting ${key}!`);
      return Reflect.set(target, key, value, receiver);
    },
  }
);

一般将handle参数说成配置对象,在配置对象中,可以定义需要拦截的操作。如果配置对象为空,那么对proxy的操作将直通目标对象。 

对proxy操作才有拦截效果,而不是目标对象。

Proxy实例的方法

当读取不存在的属性时候,抛出错误而不是返回undefined

var person = {
  name: "张三",
};

var proxy = new Proxy(person, {
  get: function (target, property) {
    if (property in target) {
      return target[property];
    } else {
      throw new ReferenceError('Property "' + property + '" does not exist.');
    }
  },
});

proxy.name; // "张三"
proxy.age; // 抛出一个错误

拦截读取继承属性

let proto = new Proxy(
  {},
  {
    get(target, propertyKey, receiver) {
      console.log("GET " + propertyKey);
      return target[propertyKey];
    },
  }
);

let obj = Object.create(proto);
obj.xxx; // "GET xxx"

数组读取负数索引(负数索引表示倒着取数)

function createArray(...elements) {
  let handler = {
    get(target, propKey, receiver) {
      let index = Number(propKey);
      if (index < 0) {
        propKey = String(target.length + index);
      }
      return Reflect.get(target, propKey, receiver);
    },
  };

  let target = [];
  target.push(...elements);
  return new Proxy(target, handler);
}

let arr = createArray("a", "b", "c");
arr[-1]; // c

实现数据的限制

let validator = {
  set: function (obj, prop, value) {
    if (prop === "age") {
      if (!Number.isInteger(value)) {
        throw new TypeError("The age is not an integer");
      }
      if (value > 200) {
        throw new RangeError("The age seems invalid");
      }
    }

    // 对于age以外的属性,直接保存
    obj[prop] = value;
  },
};

let person = new Proxy({}, validator);

person.age = 100;

person.age; // 100
person.age = "young"; // 报错
person.age = 300; // 报错

防止内部属性“_”被外部读写(通常我们以下划线开头,表示其实内部属性)

var handler = {
  get(target, key) {
    invariant(key, "get");
    return target[key];
  },
  set(target, key, value) {
    invariant(key, "set");
    target[key] = value;
    return true;
  },
};
function invariant(key, action) {
  if (key[0] === "_") {
    throw new Error(`Invalid attempt to ${action} private "${key}" property`);
  }
}
var target = {};
var proxy = new Proxy(target, handler);
proxy._prop;
// Error: Invalid attempt to get private "_prop" property
proxy._prop = "c";
// Error: Invalid attempt to set private "_prop" property

拦截——函数调用、callapply操作

var twice = {
  apply(target, ctx, args) {
    return Reflect.apply(...arguments) * 2;
  },
};
function sum(left, right) {
  return left + right;
}
var proxy = new Proxy(sum, twice);
proxy(1, 2); // 6
proxy.call(null, 5, 6); // 22
proxy.apply(null, [7, 8]); // 30

不对...in...循环生效

var handler = {
  has(target, key) {
    if (key[0] === "_") {
      return false;
    }
    return key in target;
  },
};
var target = { _prop: "foo", prop: "foo" };
var proxy = new Proxy(target, handler);
"_prop" in proxy; // false

不对for...in...循环生效

let stu1 = { name: "张三", score: 59 };
let stu2 = { name: "李四", score: 99 };

let handler = {
  has(target, prop) {
    if (prop === "score" && target[prop] < 60) {
      console.log(`${target.name} 不及格`);
      return false;
    }
    return prop in target;
  },
};

let oproxy1 = new Proxy(stu1, handler);
let oproxy2 = new Proxy(stu2, handler);

"score" in oproxy1;
// 张三 不及格
// false

"score" in oproxy2;
// true

for (let a in oproxy1) {
  console.log(oproxy1[a]);
}
// 张三
// 59

for (let b in oproxy2) {
  console.log(oproxy2[b]);
}
// 李四
// 99

拦截object.keys()

proxy baut eine Abfangschicht auf der äußeren Schicht des Zielobjekts auf (welche Operationen von außen abgefangen werden können, wird später erläutert) muss diese Schicht durchlaufen des Abfangens. Syntax
let target = {
  a: 1,
  b: 2,
  c: 3,
};

let handler = {
  ownKeys(target) {
    return ["a"];
  },
};

let proxy = new Proxy(target, handler);

Object.keys(proxy);
// [ &#39;a&#39; ]

generiert proxy über den Konstruktor. Der Parameter target ist das abzufangende Zielobjekt und der handlerCode> Parameter ist auch ein Objekt, das zum Anpassen des Abfangverhaltens verwendet wird.

Beispiel

rrreee Im Allgemeinen wird der Parameter handle als Konfigurationsobjekt bezeichnet. Im Konfigurationsobjekt können Sie die Vorgänge definieren, die abgefangen werden müssen. Wenn das Konfigurationsobjekt leer ist, werden Vorgänge auf proxy direkt zum Zielobjekt ausgeführt.

🎜Der Abfangeffekt gilt nur für Proxy-Operationen, nicht für das Zielobjekt. 🎜🎜🎜Methoden von Proxy-Instanzen🎜🎜Beim Lesen nicht vorhandener Eigenschaften wird ein Fehler ausgegeben, anstatt undefiniert zurückzugeben.🎜rrreee🎜Intercept beim Lesen geerbter Eigenschaften🎜rrreee🎜 Array-Lesung negativ Index (negativer Index bedeutet, Zahlen rückwärts abzurufen) 🎜rrreee🎜 Implementieren Sie Datenbeschränkungen 🎜rrreee🎜, um zu verhindern, dass das interne Attribut „_“ extern gelesen und geschrieben wird (normalerweise beginnen wir mit einem Unterstrich, um dies tatsächlich anzuzeigen). Interne Eigenschaften) 🎜rrreee🎜Interception – Funktionsaufrufe, call, apply-Operationen 🎜rrreee🎜wird nicht wirksam in ...in... Schleifen 🎜rrreee🎜Falsche for...in...-Schleife wird wirksam🎜rrreee🎜Abfangen der object.keys()-Methode🎜rrreee🎜🎜Quelle dieses Artikels RYF-Adresse: https://es6.ruanyifeng.com/#docs/proxy🎜🎜🎜Empfohlenes Lernen: 🎜JS Advanced Tutorial🎜🎜

Das obige ist der detaillierte Inhalt vonEin Artikel, der die Verwendung von ES6-Proxy-Proxy in JS (Code-Sharing) erläutert.. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Dieser Artikel ist reproduziert unter:chuchur.com. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen