Proxy 小结

191 阅读1分钟

Proxy 对象用于定义基本操作的自定义行为(如属性查找,赋值,枚举,函数调用等)

原文链接

proxy-ES6-阮一峰

1.基本使用

let obj = {};
let handler = {
    get(target, property) {
        console.log(`${property} 被读取`);
        return property in target ? target[property] : 3;
    },
    set(target, property, value) {
        console.log(`${property} 被设置为 ${value}`);
        target[property] = value;
    }
}
	
let p = new Proxy(obj, handler);
p.name = 'tom' //name 被设置为 tom
console.log(p.age); //age 被读取 3

2.作为验证使用(常用)

let validator = {
    set: function(obj,prop,value){
        if(prop === 'age') {
            if(!Number.isInteger(value)){
                throw new Error("年龄不是整数")
            }
            if(value > 300){
                throw new Error("年龄太大了")
            }
        }
        obj[prop] = value
    }
}

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

person.age = 100;
console.log(person.age)  //100
person.age = 10.1   //报错 年龄不是整数
person.age = 500    //报错 年龄太大了

3.实现双向绑定

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>proxy-VUE</title>
</head>
<style>
    #app {
        margin: 100px auto 0 auto;
        width: 300px;
    }
    #btn {
        margin: 10px auto;
    }
</style>
<body>
	<div id="app">
	     <input type="text" id="input" />
	     <div>您输入的是: <span id="title"></span></div>
	     <button type="button" name="button" id="btn">添加到todolist</button>
	     <ul id="list"></ul>
	</div>
</body>
<script type="text/javascript">
	// 数据绑定
	const obj = {};
    const arr = [];
    const input = document.getElementById("input");
    const title = document.getElementById("title");
    const list = document.getElementById("list");
    const btn = document.getElementById("btn");
    // 渲染todolist列表
    const Render = {
      // 初始化
      init: function(arr) {
        const fragment = document.createDocumentFragment();
        for (let i = 0; i < arr.length; i++) {
          const li = document.createElement("li");
          li.textContent = arr[i];
          fragment.appendChild(li);
        }
        list.appendChild(fragment);
      },
      addList: function(val) {
        const li = document.createElement("li");
        li.textContent = val;
        list.appendChild(li);
      }
    };
    // 监听对象
    const newObj = new Proxy(obj, {
      get: function(target, key, receiver) {
        console.log(`getting ${key}!`);
        return Reflect.get(target, key, receiver);
      },
      set: function(target, key, value, receiver) {
        console.log(target, key, value, receiver);
        if (key === "text") {
          input.value = value;
          title.innerHTML = value;
        }
        return Reflect.set(target, key, value, receiver);
      }
    });
  
    // 监听数组
    const newArr = new Proxy(arr, {
      get: function(target, key, receiver) {
        return Reflect.get(target, key, receiver);
      },
      set: function(target, key, value, receiver) {
        console.log(target, key, value, receiver);
        if (key !== "length") {
          Render.addList(value);
        }
        return Reflect.set(target, key, value, receiver);
      }
    });
    // 初始化
    window.onload = function() {
      Render.init(arr);
    };
    input.addEventListener("keyup", function(e) {
        newObj.text = e.target.value;
    });
    btn.addEventListener("click", function() {
      newArr.push(parseInt(newObj.text));
    });
</script>
</html>