前言

ES6已经出来好久了,但是工作中比较常用的只有let const声明,通过箭头函数改this指向,使用promise + async 解决异步编程,还有些数据类型方法...所以单独写一篇文章学习ES6中的proxy 和 reflect。本文属于学习笔记,可能会有错误的理解,欢迎交流指正。

基本概念

什么是元编程?这是我在网上搜到的一句话。大家可以参考理解。我的简单理解就是》改源码底层的东西,对原本的功能进行了更改。

能“介入”的对象底层操作进行的过程中,并加以影响。元编程中的 元 的概念可以理解为 程序 本身。”元编程能让你拥有可以扩展程序自身能力“。 ---- https://www.zhihu.com/question/23856985 知乎问答参考

Reflect: 用于替代直接调用Object的方法,它并不是一个函数对象,没有constructor,所有不要使用new操作符。

Proxy: 用于自定义的对象的行为,比如修改set和get,感觉是es5的Object.defineProperty()方法的es6升级版。

一些资料链接:

MDN-Reflect:MDN 上的 Reflect 官方文档

MDN-Proxy: MDN 上的 Proxy 官方文档

MDN-元编程:MDN 官方文档教程,介绍了元编程的概念

ECMAScript 6 入门 :阮老师的es6入门,对es6还没入门的同学可以全文阅读一番

Reflect & Proxy的联系:两者拥有完全一致的API方法,具体可参考mdn,Reflect一般在Proxy中需要处理默认行为时使用。

编程案例

俗话说的好,理论只是纸上谈兵,还是实践中学习这些元编程方法。

数据劫持,验证操作

let handler = {
get: function(target, key){
return key in target ? target[key] : 37;
},
set: function(target, key, value) {
if (key === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer');
}
if (value > 200) {
throw new RangeError('The age seems invalid');
}
} // The default behavior to store the value
target[key] = value;
}
};
let p = new Proxy({}, handler);
p.a = 1;
p.b = undefined;
person.age = 100; console.log(person.age);
// 100 person.age = 'young';
// 抛出异常: Uncaught TypeError: The age is not an integer person.age = 300;
// 抛出异常: Uncaught RangeError: The age seems invalid
console.log(p.a, p.b); // 1, undefined console.log('c' in p, p.c); // false, 37

这是一个非常典型的案例,使用vue的同学都知道vue是通过数据劫持的方法来完成数据绑定的,通过proxy代理对象的set,get方法同样可以完成数据劫持的目的,

函数节流

const createThrottleProxy = (fn, rate) => {
let lastClick = Date.now() - rate;
return new Proxy(fn, {
apply(target, context, args) {
if (Date.now() - lastClick >= rate) {
fn.bind(target)(args);
lastClick = Date.now();
}
}
});
}; const handler = () => console.log('Do something...');
const handlerProxy = createThrottleProxy(handler, 1000);
document.addEventListener('scroll', handlerProxy);

该实例通过proxy的handler.apply()拦截了函数调用,当只有时间超过1s时候函数才会再次被调用

单例模式

// makes a singleton proxy for a constructor function
function makeSingleton(func) {
let instance,
handler = {
construct: function (target, args) {
if (!instance) {
instance = new func();
}
return instance;
}
};
return new Proxy(func, handler);
} // 以这个为 constructor 为例
function Test() {
this.value = 0;
} // 普通创建实例
const t1 = new Test(),
t2 = new Test();
t1.value = 123;
console.log('Normal:', t2.value); // 0 - 因为 t1、t2 是不同的实例 // 使用 Proxy 来 trap 构造函数, 完成单例模式
const TestSingleton = makeSingleton(Test),
s1 = new TestSingleton(),
s2 = new TestSingleton();
s1.value = 123;
console.log('Singleton:', s2.value); // 123 - 现在 s1、s2 是相同的实例。

通过proxy的construct方法 拦截,让不同的实例指向了相同的constructer,达到单例模式的目的。

后记

不得不说实践出真知啊,行文至此,参考了mdn,网上也搜了很多相关资料,案例借鉴,自己对Proxy的理解也上了一个层次,最近本想深入canvas,但感觉不做图形方面的工作的话,真的难以应用。下篇文章先预定写全栈应用或者 vue源码方面的。

最近想深入一下计算机原理,请大佬推荐一些计算机原理方面的书籍,当然不限于计算机,前端方面也可以。红宝书,精粹,dom编程艺术,js忍者秘籍,你不知道的js,css揭秘,node实战这些已经看过了,就不要重复推荐了,这些都是我看过觉得不错的书。本人零基础,大学自学的一点前端知识,感觉需要扩展一下。

ES6中的元编程-Proxy & Reflect的更多相关文章

  1. es6总结(七)--proxy & reflect

  2. 详解es6中Proxy代理对象的作用

    在es6中新添加了Proxy,那么它有什么作用啊?Proxy本意为代理,而es6中的Proxy也就是代理对象,那么代理对象感觉听起来很模糊,在这里就解释一下Proxy代理对象的作用. Proxy的主要 ...

  3. .Net元编程【Metaprogramming in NET】 序-翻译

    最近在看这本书,比较实用.抽点时间把公开的部分内容简单的翻译了一下,下文是序部分. 书的具体地址为: http://www.amazon.cn/Metaprogramming-in-NET-Hazza ...

  4. C++ 元编程 —— 让编译器帮你写程序

    目录 1 C++ 中的元编程 1.1 什么是元编程 1.2 元编程在 C++ 中的位置 1.3 C++ 元编程的历史 2 元编程的语言支持 2.1 C++ 中的模板类型 2.2 C++ 中的模板参数 ...

  5. C++11模版元编程

    1.概述 模版元编程(template metaprogram)是C++中最复杂也是威力最强大的编程范式,它是一种可以创建和操纵程序的程序.模版元编程完全不同于普通的运行期程序,它很独特,因为模版元程 ...

  6. 如何在webpack开发中利用vue框架使用ES6中提供的新语法

    在webpack中开发,会遇到一大推问题,特别是babel6升级到babel7,要跟新一大推插件,而对于安装babel的功能就是在webpack开发中,vue中能够是用ES6的新特性: 例如ES6中的 ...

  7. C++值元编程

    --永远不要在OJ上使用值元编程,过于简单的没有优势,能有优势的编译错误. 背景 2019年10月,我在学习算法.有一道作业题,输入规模很小,可以用打表法解决.具体方案有以下三种: 运行时预处理,生成 ...

  8. 元编程 (meta-programming)

    元编程 (meta-programming) 术语 meta:英语前缀词根,来源于希腊文.中国大陆一般翻译成"元". 在逻辑学中,可以理解为:关于X的更高层次,同时,这个更高层次的 ...

  9. 利用ES6中的Proxy和Reflect 实现简单的双向数据绑定

    利用ES6中的Proxy (代理) 和 Reflect 实现一个简单的双向数据绑定demo. 好像vue3也把 obj.defineProperty()  换成了Proxy+Reflect. 话不多说 ...

随机推荐

  1. Spring mvc项目,使用jetty插件和tomcat路径相差一个项目名

    pom.xml: jetty 插件配置: <plugin> <groupId>org.mortbay.jetty</groupId> <artifactId& ...

  2. vue 开发系列(四) vue 使用外部JS

    概要 在开发时我们会经常需要使用到外部的JS,这样我们需要引入外部js,然后进行使用. 实现方法 我们在开发的过程中需要使用到 sha256 将用户的密码进行加密传输. 我们对js进行一点点改造. f ...

  3. 解决python代码中含有中文报错

    python中写入中文时报错如下图所示: 依照网上解决方法:在py文件中加入:#encoding=utf-8 然后继续报错如下图所示: 解决方法: 在py文件中加入: import sysreload ...

  4. jdk1.6的配置

    执行下列命令安装jdk1.7 /usr/lib/jvm$ sudo apt-get install openjdk-7-jdk openjdk-7-jre 会得到下面这两个文件: 查看当前jdk版本: ...

  5. 5W2H+35问

    之前看到的一个非常好且全面的做事方法论.

  6. 基于S2AFCM的子主题划分

    http://sztsg.czlib.net:8088/interlibSSO/goto/2/=jmr9bmjh9mds/KXReader/Detail?dbcode=CJFD&filenam ...

  7. Vue上传文件:ElementUI中的upload实现

    一.上传文件实现 两种实现方式: 1.直接action <el-upload  .利用before-upload属性 此种方式有个弊端,就是action是必选的参数,那么action如果和pos ...

  8. nginx搭建简单的图片服务器

    传统项目一般实现图片上传的话,都会在tomcat下面建立一个图片文件夹,上传成功后,用户可以直接访问, http://ip:port/project/images/xxx.jpg; 这样在用户量少的时 ...

  9. 使用Golang+Mongodb打造你的第一个站点

    很多人推荐MEAN来开发站点.MEAN就是M:mongodb,E:expressjs.A:angular最后的N:nodejs. 但是如果你亲身的体会到了js的嵌套回调的话你就会想换换别的办法了.虽然 ...

  10. day17(tomcat的安装,HTTP)

    Tomcat Tomcat是个小型服务器,由apache组织编写,转为发布java程序而写. 安装步骤: 官网:http://tomcat.apache.org/ 下载地址:http://tomcat ...