首页前端开发JavaScript一文讲解JS中ES6代理Proxy用法(代码分享)

一文讲解JS中ES6代理Proxy用法(代码分享)

时间2024-01-30 05:24:03发布访客分类JavaScript浏览809
导读:收集整理的这篇文章主要介绍了一文讲解JS中ES6代理Proxy用法(代码分享),觉得挺不错的,现在分享给大家,也给大家做个参考。之前的文章《浅析vue中web前端项目优化(附代码)》中,给大家了解了vue中web前端项目优化。下面本篇文章给...
收集整理的这篇文章主要介绍了一文讲解JS中ES6代理Proxy用法(代码分享),觉得挺不错的,现在分享给大家,也给大家做个参考。

之前的文章《浅析vue中web前端项目优化(附代码)》中,给大家了解了vue中web前端项目优化。下面本篇文章给大家了解一下JS中ES6代理Proxy用法,伙伴们来看看一下。

PRoxy的概念

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;
     // 100person.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" propertyproxy._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);
     // 6proxy.call(null, 5, 6);
     // 22proxy.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;
// truefor (let a in oproxy1) {
      console.log(oproxy1[a]);
}
// 张三// 59for (let b in oproxy2) {
      console.log(oproxy2[b]);
}
    // 李四// 99

拦截object.keys()方法

let target = {
  a: 1,  b: 2,  c: 3,}
    ;
let handler = {
  ownKeys(target) {
        return ["a"];
  }
,}
    ;
    let proxy = new Proxy(target, handler);
    Object.keys(proxy);
    // [ 'a' ]

本文来源RYF地址:https://es6.ruanyifeng.COM/#docs/proxy

推荐学习:JS高级教程

以上就是一文讲解JS中ES6代理Proxy用法(代码分享)的详细内容,更多请关注其它相关文章!

声明:本文内容由网友自发贡献,本站不承担相应法律责任。对本内容有异议或投诉,请联系2913721942#qq.com核实处理,我们将尽快回复您,谢谢合作!

上一篇: 深入了解Node.js util模块的prom...下一篇:JS数组学习之判断数组元素是不是...猜你在找的JavaScript相关文章 html font标签如何设置字体大小?html font标签属性用法介绍2022-05-16vue3+TypeScript+vue-router的使用方法2022-04-16vue3获取当前路由地址2022-04-16如何利用React实现图片识别App2022-04-16JavaScript展开运算符和剩余运算符的区别详解2022-04-16微信小程序中使用vant框架的具体步骤2022-04-16Vue elementUI表单嵌套表格并对每行进行校验详解2022-04-16如何利用Typescript封装本地存储2022-04-16微信小程序中wxs文件的一些妙用分享2022-04-16JavaScript的Set数据结构详解2022-04-16 其他相关热搜词更多phpjavapython程序员loadpost-format-gallery

若转载请注明出处: 一文讲解JS中ES6代理Proxy用法(代码分享)
本文地址: https://pptw.com/jishu/592096.html
如何通过jQuery给一个元素添加单击和双击事件 深入了解Node.js util模块的promisify()方法

游客 回复需填写必要信息