浅谈es6中的元编程


Posted in Javascript onDecember 01, 2020

何为元编程?

「编写能改变语言语法特性或者运行时特性的程序」。换言之,一种语言本来做不到的事情,通过你编程来修改它,使得它可以做到了,这就是元编程。

meta-programming元编程中的 元 的概念可以理解为 程序 本身。”元编程能让你拥有可以扩展程序自身能力

举个例子:

if (a == 1 && a == 2 && a == 3) {
  console.log("done");
}

怎样才能让这个条件满足,输出done。按照正常的逻辑是无法完成的,毕竟一个值不可能同时满足等于1、2、3

这是就可以用到元编程来改变这个不可能

let a = {
  [Symbol.toPrimitive]: ((i) => () => ++i)(0)
}

if (a == 1 && a == 2 && a == 3) {
  console.log("done");
}
// done

Symbol.toPrimitive在对象转换为原始值的时候会被调用,初始值为1,调用一次+1,就可以满足a == 1 && a == 2 && a == 3,同时Symbol.toPrimitive也可以接受一个参数hint,hint的取值为number、string、default

let obj = {
  [Symbol.toPrimitive](hint) {
    switch (hint) {
      case "number":
        return 123;
      case "string":
        return "str";
      case "default":
        return "default";
    }
  }
}
console.log(1-obj); // -122
console.log(1+obj); // 1default
console.log(`${obj}`); // str

还有哪些元编程?

proxy

es5的Object.defineProperty()方法的es6升级版,用于自定义的对象的行为

let leon = {
  age: 30
}
const validator = {
  get: function(target, key){
    // 若没这个属性返回37
    return key in target ? target[key] : 37;
  },
  set(target,key,value){
    if(typeof value!="number" || Number.isNaN(value)){
      throw new Error("年龄得是数字");
    }
  }
}
const proxy = new Proxy(leon,validator);
console.log(proxy.name);
// 37
proxy.age = "hi";
// Error: 年龄得是数字

reflect-metadata

你可以通过装饰器来给类添加一些自定义的信息。然后通过反射将这些信息提取出来。当然你也可以通过反射来添加这些信息

require("reflect-metadata")
class C {
  // @Reflect.metadata(metadataKey, metadataValue)
  method() {
  }
}
Reflect.defineMetadata("name", "jix", C.prototype, "method");

let metadataValue = Reflect.getMetadata("name", C.prototype, "method");
console.log(metadataValue);
// jix

应用

拓展数组索引访问

负索引访问,使array[-N] 与 array[array.length - N] 相同

let array = [1, 2, 3];

array = new Proxy(array, {
 get(target, prop, receiver) {
  if (prop < 0) {
   console.log(prop, 'prop')
   prop = +prop + target.length;
  }
  return Reflect.get(target, prop, receiver);
 }
});


console.log(array[-1]); // 3
console.log(array[-2]); // 2

数据劫持

let handlers = Symbol('handlers');

function makeObservable(target) {
 // 初始化存储 handler 的数组
 target[handlers] = [];

 // 存储 handler 函数到数组中以便于未来调用
 target.observe = function(handler) {
  this[handlers].push(handler);
 };

 // 创建代理以处理更改
 return new Proxy(target, {
  set(target, property, value, receiver) {
   // 转发写入操作到目标对象
   let success = Reflect.set(...arguments);
   // 如果设置属性的时候没有报错
   if (success) {
    // 调用所有 handler
    target[handlers].forEach(handler => handler(property, value));
   }
   return success;
  }
 });
}

let user = {};

user = makeObservable(user);

user.observe((key, value) => {
 console.log(`SET ${key}=${value}`);
});

user.name = "John";
// SET name=John

到此这篇关于浅谈es6中的元编程的文章就介绍到这了,更多相关es6 元编程内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木! 

Javascript 相关文章推荐
javascript 短路法代码精简
Aug 20 Javascript
Ajax+Json 级联菜单实现代码
Oct 27 Javascript
关于Aptana Studio生成自动备份文件的解决办法
Dec 23 Javascript
js在数组中删除重复的元素自保留一个(两种实现思路)
Aug 22 Javascript
使用jquery操作session方法分享
Jan 22 Javascript
js实现跨域的方法实例详解
Jun 24 Javascript
原生JS实现自定义滚动条效果
Oct 27 Javascript
使用jQuery实现鼠标点击左右按钮滑动切换
Aug 04 jQuery
200行代码实现blockchain 区块链实例详解
Mar 14 Javascript
webpack 静态资源集中输出的方法示例
Nov 09 Javascript
js JSON.stringify()基础详解
Jun 19 Javascript
简单实现节流函数和防抖函数过程解析
Oct 08 Javascript
Vue.js桌面端自定义滚动条组件之美化滚动条VScroll
Dec 01 #Vue.js
微信小程序轮播图swiper代码详解
Dec 01 #Javascript
利用JavaScript模拟京东按键输入功能
Dec 01 #Javascript
layui使用及简单的三级联动实现教程
Dec 01 #Javascript
vue开发chrome插件,实现获取界面数据和保存到数据库功能
Dec 01 #Vue.js
编写v-for循环的技巧汇总
Dec 01 #Javascript
jquery实现拖拽添加元素功能
Dec 01 #jQuery
You might like
php中让上传的文件大小在上传前就受限制的两种解决方法
2013/06/24 PHP
PHP文件大小格式化函数合集
2014/03/10 PHP
typecho插件编写教程(三):保存配置
2015/05/28 PHP
ThinkPHP中数据操作案例分析
2015/09/27 PHP
Yii框架页面渲染操作实例详解
2019/07/19 PHP
基于jquery的图片的切换(以数字的形式)
2011/02/14 Javascript
JQuery-tableDnD 拖拽的基本使用介绍
2013/07/04 Javascript
JS控件ASP.NET的treeview控件全选或者取消(示例代码)
2013/12/16 Javascript
javascript实现iframe框架延时加载的方法
2014/10/30 Javascript
原生javascript实现图片弹窗交互效果
2015/01/12 Javascript
Javascript小技能总结(推荐)
2016/06/02 Javascript
Vue+Element使用富文本编辑器的示例代码
2017/08/14 Javascript
js es6系列教程 - 新的类语法实战选项卡(详解)
2017/09/02 Javascript
jquery自定义显示消息数量
2017/12/19 jQuery
详解Immutable及 React 中实践
2018/03/01 Javascript
Vue表单输入绑定的示例代码
2018/11/01 Javascript
微信小程序实现单选选项卡切换效果
2020/06/19 Javascript
微信小程序实现横向滚动导航栏效果
2019/12/12 Javascript
webpack3.0升级4.0的方法步骤
2020/04/02 Javascript
Vue组件为什么data必须是一个函数
2020/06/11 Javascript
Vue利用localStorage本地缓存使页面刷新验证码不清零功能的实现
2020/09/04 Javascript
Vue看了就会的8个小技巧
2021/01/21 Vue.js
用Python给文本创立向量空间模型的教程
2015/04/23 Python
python字符串中的单双引
2017/02/16 Python
Python使用正则表达式实现文本替换的方法
2017/04/18 Python
windows下python之mysqldb模块安装方法
2017/09/07 Python
Python与R语言的简要对比
2017/11/14 Python
python学习基础之循环import及import过程
2018/04/22 Python
python3处理含有中文的url方法
2018/05/10 Python
pygame实现五子棋游戏
2019/10/29 Python
Python类绑定方法及非绑定方法实例解析
2020/10/09 Python
python 基于opencv去除图片阴影
2021/01/26 Python
类和结构的区别
2012/08/15 面试题
弘扬焦裕禄精神践行三严三实心得体会
2014/10/13 职场文书
上班旷工检讨书
2015/08/15 职场文书
2015年教师个人业务工作总结
2015/10/23 职场文书