十一、Proxy 、Reflect

   ①、Proxy 的概念和常用方法

{
let obj = { //1、定义原始数据对象 对用户不可见
time: '2017-09-20',
name: 'net',
_r:
}; let monitor = new Proxy(obj, { //2、通过Proxy新生成一个对象 映射obj 代理所有对obj的操作
//拦截对象的属性读取
get(target, key){ //设置访问规则
return target[key].replace('', '');
},
set(target, key, value){ //设置修改规则
if (key === name) {
return target[key] = value; //只允许修改name
} else {
return target[key];
}
}, //拦截 key in object 操作
has(target, key){
if (key === 'name') {
return target[key]; //只暴露name属性
} else {
return false
}
}, //拦截对 delete 操作
deleteProperty(target, key){
if (key.startsWith('_')) { //只允许删除以 '_'开头的属性
delete target[key];
} else {
return target[key];
}
}, //拦截Object.keys(),Object.getOwnPropertySymbols(),Object,getOwnPropertyNames() 等方法
ownKeys(target){
return Object.keys(target).filter(item=>item != 'time'); //过滤掉 time 属性
}
});
//3、用户访问的是 monitor
console.log('get', monitor.time); //get 2018-09-20 读取的数据被代理修改了
monitor.time = '2018-01-15';
monitor.name = 'com';
console.log('set', monitor.time, monitor.name); //set 2018-09-20 net time属性的修改无法生效 console.log('has', 'name' in monitor, 'time' in monitor); //has true false time属性被我们拦截了 delete monitor.time;
delete monitor._r;
console.log('delete', monitor); //delete Proxy {time: "2017-09-20", name: "net"} _r属性被删除 而对time的操作被拦截 console.log('ownKeys', Object.keys(monitor)) //ownKeys ["name"] time属性被拦截
}

  ②、Reflect 的概念和用法

{              **同Proxy
let obj = {
time: '2017-09-20',
name: 'net',
_r:
};
// Reflect.get/set/has/ownKeys...(target,key,value);
console.log('Reflect get', Reflect.get(obj, 'time')); //Reflect get 2017-09-20 console.log('Reflect set', Reflect.set(obj, 'name', 'com'), obj);
//Reflect set true {time: "2017-09-20", name: "com", _r: 123} console.log('Reflect has', Reflect.has(obj, '_r')); //Reflect has true

  ③、使用 Proxy 和 Reflect 实现业务的解耦

function validator(target, validator) {
return new Proxy(target, { //返回一个对target的代理
_validator: validator, //接收 验证规则
set(target, key, value, proxy){ //定义 对 target的 修改规则
if (target.hasOwnProperty(key)) { //判断 target 的 key 是否存在
let vali = this._validator[key]; //去除对应key 的验证规则
if (!!vali(value)) {
return Reflect.set(target, key, value, proxy);
} else {
throw Error(`无法设置${value}到${key}`);
}
} else {
throw Error(`${key}不存在`)
}
}
});
}
const userValidator = { //定义验证规则
name(val){
return /[a-zA-Z0-9_]{3,12}/.test(val);
},
phone(val){
return /^1[3|4|5|8][0-9]\d{4,8}$/.test(val)
}
} class User{
constructor(name,phone){
this.name=name;
this.phone= phone;
return validator(this,userValidator); //得到一个 user的代理对象
}
}
let u = new User(); //初始化 得到 user 的代理
//u.name = 'a' //不符合 验证规则 抛出错误 无法设置a到name
console.log(u.name='Lain',u.phone=13797154666,u); //Proxy {name: "Lain", phone: 13797154666}

ES6新特性使用小结(四)的更多相关文章

  1. ES6新特性使用小结(三)

    九.数据类型 Symbol /* * Symbol 数据类型 概念: Symbol 提供一个独一无二的值 * */ { let a1 = Symbol(); let a2 = Symbol(); co ...

  2. ES6新特性使用小结(一)

    一.let const 命令 'use strict'; /*function test(){ //let a = 1; for(let i=1;i<3;i++){ console.log(i) ...

  3. ES6新特性使用小结(六)

    十三.promise 异步编程 ①.使用 promise 模拟异步操作 { //ES5 中的 callback 解决 异步操作问题 let ajax = function (callback) { c ...

  4. ES6新特性使用小结(二)

    六.Array 扩展 /* * Array Api Array.of 数组的构建 * */ { let arr = Array.of(, , , , , ); console.log(arr); // ...

  5. ES6新特性使用小结(五)

    十二.class 与 extends ①.类的基本定义和生成实例 { class Parent{ constructor(name='Lain'){ //定义构造函数 this.name = name ...

  6. ES6新特性之模板字符串

    ES6新特性概览  http://www.cnblogs.com/Wayou/p/es6_new_features.html 深入浅出ES6(四):模板字符串   http://www.infoq.c ...

  7. ES6新特性概览

    本文基于lukehoban/es6features ,同时参考了大量博客资料,具体见文末引用. ES6(ECMAScript 6)是即将到来的新版本JavaScript语言的标准,代号harmony( ...

  8. Atitit js版本es5 es6新特性

    Atitit js版本es5 es6新特性 Es5( es5 其实就是adobe action script的标准化)1 es6新特性1 Es5( es5 其实就是adobe action scrip ...

  9. ES6新特性:Proxy代理器

    ES6新特性:Proxy: 要使用的话, 直接在浏览器中执行即可, node和babel目前还没有Proxy的polyfill;,要使用的话,直接在浏览器中运行就好了, 浏览器的兼容性为:chrome ...

随机推荐

  1. iOS开发数据库-FMDB

    前言 FMDB是以OC的方式封装了SQLite的C语言API,使用起来更加面向对象,省去了很多麻烦.冗余的C语言代码:对比苹果自带的Core Data框架,更加轻量级和灵活:提供了多线程安全的数据库操 ...

  2. 改变Ecplise项目窗口字体样式

    Eclipse\plugins\org.eclipse.ui.themes_1.1.1.v20151026-1355\css e4-dark_win.css CTabFolder Tree, CTab ...

  3. labview初步理解

    1.labview是NI公司开发的一款以图形方式开发程序(G语言)的程序开发环境软件.它的作用与VS一样,是一种程序开发环境.只是vs是以文本语言开发环境而已. 2.labview最广泛应用于开发测试 ...

  4. 善用搜索--->描述问题 [关于SwipeRefreshLayout]

    遇到了一个问题,SwipeRefreshLayout没法在加载listView之前呈现progressBar.我一直在想,是不是只能在listView加载出来才能呈现它. 发邮件问了一个开发者,他说他 ...

  5. ACM学习历程—HDU1717 小数化分数2(gcd)

    Description Ray 在数学课上听老师说,任何小数都能表示成分数的形式,他开始了化了起来,很快他就完成了,但他又想到一个问题,如何把一个循环小数化成分数呢? 请你写一个程序不但可以将普通小数 ...

  6. C++ STL std::wstring_convert处理UTF8

    #include <iostream> #include <string> #include <locale> #include <codecvt> # ...

  7. tcpdump抓包工具用法说明

    tcpdump采用命令行方式对接口的数据包进行筛选抓取,其丰富特性表现在灵活的表达式上. 不带任何选项的tcpdump,默认会抓取第一个网络接口,且只有将tcpdump进程终止才会停止抓包. 例如: ...

  8. 树——平衡二叉树插入和查找的JAVA实现(2):增加删除方法

    package com.tomsnail.data.tree; /** * AVL二叉平衡树 * @author tomsnail * @date 2015年3月30日 下午4:35:50 */ pu ...

  9. JavaScript:bootstrap 模态框的简单应用

    最近用上了bootstrap这个强大的前端框架,有空来总结一下.这里记录下模态框的简单应用. 首先,要在页面中引入相应的js.css文件 <link href="css/bootstr ...

  10. cocos2dx 3.0 用ClippingNode做游戏的新手引导

    转自:http://blog.csdn.net/star530/article/details/20851263 本篇介绍的是用ClippingNode 做游戏的新手引导,额,或者说是做新手引导的一种 ...