proxy reflect使用

使用Proxy实现观察者模式

// 观察队列
const queueObservers = new Set();

// 观察队列添加方法
const observers = (fn) => queueObservers.add(fn);

// 观察对象
const observable = (obj) =>
  new Proxy(obj, {
    
    
    set(target, key, value, receiver) {
    
    
      Reflect.set(target, key, value);
      queueObservers.forEach((fn) => fn());
    },
    get(target, key, receiver) {
    
    
      queueObservers.forEach((fn) => fn());
      return Reflect.get(target, key);
    },
  });

// 使用规则:
// 观察响应方法
observers(function () {
    
    
  console.log('开始观察');
});
// 观察对象(对象可观察化)
const person = observable({
    
    
  name: '张三',
  age: 18,
});
person.name = '刘武';
console.log(person.name);

使用proxy实现数组读取负数的索引

const readArray = (arr) =>
  new Proxy(arr, {
    
    
    set(target, key, value, receiver) {
    
    
      if (Number(key) < 0) {
    
    
        Reflect.set(target, Number(key) + target.length, value);
      } else {
    
    
        Reflect.set(target, key, value);
      }
    },
    get(target, key, receiver) {
    
    
      console.log(Number(key))
      if (Number(key) < 0) {
    
    
        return Reflect.get(target, Number(key) + target.length);
      } else {
    
    
        return Reflect.get(target, key);
      }
    },
  });

const arr = readArray([1, 2, 4, 5, 6, 7]);
console.log(arr[2]);
const obj = readArray({
    
    name:'1'})
console.log(obj.name)

实现生成各种 DOM 节点的通用函数

// 元素
// 属性
// 文本
const createDom = new Proxy(
  {
    
    },
  {
    
    
    get(target, tag) {
    
    
      return function (attrs = {
    
    }, ...children) {
    
    
        const el = document.createElement(tag); // 创建标签
        for (key in attrs) {
    
    
          el.setAttribute(key, attrs[key]); // 设置属性
        }
        for (let child of children) {
    
    
          if (typeof child == 'string') {
    
    
            child = document.createTextNode(child); // 生成文本节点
          }
          el.appendChild(child);
        }
        return el;
      };
    },
  },
);

const el = createDom.div(
  {
    
    
    style:
      'width: 600px;height: 200px;border: 1px solid #000;text-align: center;line-height: 200px;',
  },
  '去百度',
  createDom.a({
    
     href: 'https://www.baidu.com' }, '百度'),
);

document.body.appendChild(el);

reduce

const double = (x) => x + x;
const triple = (x) => 3 * x;
const quadruple = (x) => 4 * x;

// 函数返回函数
const pipe = (...functions) => (input) => functions.reduce((acc, fn) => fn(acc), input);

const multiply6 = pipe(double, triple);

multiply6(6);

将读取属性的操作(get),转变为执行某个函数,从而实现属性的链式操作

const pipe = function (value) {
    
    
  const funcStack = [];
  const proxy = new Proxy(
    {
    
    },
    {
    
    
      get(target, key) {
    
    
        if (key === 'get') {
    
    
          return funcStack.reduce(function (val, fn) {
    
    
            return fn(val);
          }, value);
        }
        funcStack.push(window[key]);
        return proxy;
      },
    },
  );
  return proxy;
};

var double = (n) => n * 2;
var pow = (n) => n * n;

const a = pipe(3).double.pow.get;
console.log(a);

猜你喜欢

转载自blog.csdn.net/qq_36303110/article/details/110443068