• proxy:代理

Proxy 用于修改某些操作的默认行为,等同于在语言层面做出修改,所以属于一种“元编程”(meta programming),即对编程语言进行编程

Proxy 可以理解成,在目标对象之前架设一层“拦截”,外界对该对象的访问,都必须先通过这层拦截,因此提供了一种机制,可以对外界的访问进行过滤和改写.Proxy 这个词的原意是代理,用在这里表示由它来“代理”某些操作,可以译为“代理器”

主要是扩展 / 增强 对象的一些功能

比如说 Vue中的 Vue.key.Codes.enter=65


proxy作用:

Vue中的拦截,上报,扩展功能,统计,增强功能等的

proxy是设计模式的一中,代理模式


语法:
new Proxy(target,handler);

let obj = new Proxy(被代理的对象,对对立对象的操作)

  • 注意:被代理的对象可以是null

    hander是一个json:
<script > {
      set(){
     },//设置的时候干的事 get(){
     },// 获取对象属性 deleteProperty(){
     },//删除 has(){
     },//判断有没有 apply(){
     }//调用函数的处理 // 等等 } </script>

如:利用proxy创建元素:

<script > const DOM = new Proxy({
     }, {
      get(target, property) {
      // property 就是 DOM.xx 里面的xxx // console.log(target, property); // ...:扩展剩余参数 return function (attr = {
     }, ...children) {
      // console.log(attr, children); const el = document.createElement(property); for (let key of Object.keys(attr)) {
      // 为el添加属性 el.setAttribute(key, attr[key]); } //再添加子元素 for (let child of children) {
      if (typeof child == 'string') {
      child = document.createTextNode(child); } el.appendChild(child); } return el; } } }); let oDiv = DOM.div({
     id: 'div1', class: 'aaa'}, '我是div', '呵呵呵'); console.log(oDiv); </script>

利用proxy创建元素及其子元素:

<script > const DOM = new Proxy({
     }, {
      get(target, property) {
      // property 就是 DOM.xx 里面的xxx // console.log(target, property); // ...:扩展剩余参数 return function (attr = {
     }, ...children) {
      // console.log(attr, children); const el = document.createElement(property); for (let key of Object.keys(attr)) {
      // 为el添加属性 el.setAttribute(key, attr[key]); } //再添加子元素 for (let child of children) {
      if (typeof child == 'string') {
      child = document.createTextNode(child); } el.appendChild(child); } return el; } } }); //只要用DOM创建元素就调用了代理 let oDiv = DOM.div({
     id: 'div1', class: 'aaa'}, '我是div', '呵呵呵'); console.log(oDiv); </script>

使用set进行拦截 和
实现一个,访问对象身上的属性,默认不存在的时候返回undefined,希望如果不存在,返回错误(警告)信息,如:

<script > {
      // 使用set进行拦截 let obj = new Proxy({
     }, {
      set(target, prop, value) {
      console.log(target, prop, value); } }); obj.a = 132; console.log("split---"); } // 设置一个年龄保证为整数,大于18,不能超过200 let obj = new Proxy({
     }, {
      set(target, prop, value) {
      if (prop == 'age') {
      if (!Number.isInteger(value)) {
      throw new TypeError(`年龄必须为整数`); } if (value > 200) {
      throw new RangeError(`年龄超标了,必须小于200岁`); } } target[prop] = value; } }); obj.a = 123; obj.name = 'kirin'; console.log(obj); // 报错 // obj.age = 13.5; obj.age = 13; /* deleteProperty():删除,拦截 has():检测有没有 * */ </script>

利用proxy删除与判断:

<script > let json = {
      a: 1, b: 2 }; let newJson = new Proxy(json, {
      deleteProperty(target, property) {
      console.log(`你要删除${
       property}属性`); //TODO delete target[property]; }, has(target, property) {
      console.log(`你判断是否存在,调用has方法了`); //TODO return property in target; } }); console.log('a' in newJson); delete newJson.a; console.log(newJson); </script>

apply():拦截方法

<script > function fn() {
      return `我是函数`; } let newFn = new Proxy(fn, {
      apply(target, thisArg, argArray) {
      return `函数吗?` } }); console.log(newFn()); </script>

Reflect.apply(调用的函数,this指向,参数数组);
利用apply进行拦截方法:

<script > function sum(a, b) {
      return a + b; } let newSum = new Proxy(sum, {
      apply(target, context, args) {
      // context:指向 // console.log(target, context, args); // console.log(...arguments) // Reflect:反射 return Reflect.apply(...arguments)**2; } }) console.log(newSum(2, 3)); </script>

还有:

<script > // console.log(Math.ceil(5.4)); // let rel = Reflect.apply(Math.ceil, null, [9.8]); // console.log(rel); function show(...args) {
      console.log(this) console.log(args); } // show(1,2,3,4); // show.call('abc', 1, 2, 3, 4); // show.apply('abc', [1, 2, 3, 4]); Reflect.apply(show, 'aaaa', [1, 2, 3, 4]); </script>

Reflect:反射

<script > // 之前的检测方法 console.log('assign' in Object); // 以后的检测方法可能一直是: console.log(Reflect.has(Object, 'assign')); </script>

还有:

<script > let json = {
     a: 1, b: 2}; /*delete json.a;//删除 console.log(json);*/ Reflect.deleteProperty(json, 'a');//删除 console.log(json); </script>

Object.xxxx 语言内部的方法

Object.defineProperty

放到Reflect对象身上

通过Reflect对象身上直接拿到语言内部东西