十一、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. CATTI二级口译训练

    Vice chancellor, faculty members and dear students, It is my great pleasure and privilege to visit C ...

  2. IE不支持HTML5表单属性placeholder的解决办法

    1. [代码][JavaScript]代码 (function ($) {    $.fn.placeholder = function (options) {        var defaults ...

  3. C#高性能Socket服务器SocketAsyncEventArgs的实现(IOCP)

    网址:http://blog.csdn.net/zhujunxxxxx/article/details/43573879 引言 我一直在探寻一个高性能的Socket客户端代码.以前,我使用Socket ...

  4. codeforces 658D D. Bear and Polynomials(数学)

    题目链接: D. Bear and Polynomials time limit per test 2 seconds memory limit per test 256 megabytes inpu ...

  5. 【LeetCode】051. N-Queens

    题目: The n-queens puzzle is the problem of placing n queens on an n×n chessboard such that no two que ...

  6. linux 遍历目录+文件(优化版本)

    c++17 filesystem, regex 遍历目录 #include <stdio.h> #include <sys/types.h> #include <dire ...

  7. S5pv210 HDMI 接口在 Linux 3.0.8 驱动框架解析

    作者:liukun321 咕唧咕唧 日期:2014.1.18 转载请标明作者.出处:http://blog.csdn.net/liukun321/article/details/18452663 本文 ...

  8. selenium上传文件,怎么操作

    #通过os.path.abspath()方法,打开图片的绝对路径,然后,定位上传按钮,然后,send_keys()方法中,添加这个文件路径就可以了

  9. TripAdvisor architecture 2011/06

    http://highscalability.com/blog/2011/6/27/tripadvisor-architecture-40m-visitors-200m-dynamic-page-vi ...

  10. 2.6用tr进行转换

    tr可以对来自标准输入的内容进行字符替换.字符删除以及重复字符压缩.它可以将一组字符变成另一组字符,因而通常也被称为转换命令. 1.tr只能通过stdin(标准输入),而无法通过命令行参数来接受输入. ...