浅谈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 动态创建VML的方法
Oct 14 Javascript
js写的方法实现上传图片之后查看大图
Mar 05 Javascript
JavaScript字符串对象substr方法入门实例(用于截取字符串)
Oct 16 Javascript
JS实现随机乱撞彩色圆球特效的方法
May 05 Javascript
基于jQuery.Hz2Py.js插件实现的汉字转拼音特效
May 07 Javascript
在JavaScript的AngularJS库中进行单元测试的方法
Jun 23 Javascript
Bootstrap下拉菜单效果实例代码分享
Jun 30 Javascript
js实现的在线调色板功能完整实例
Dec 21 Javascript
浅谈webpack 自动刷新与解析
Apr 09 Javascript
vue中利用Promise封装jsonp并调取数据
Jun 18 Javascript
vue递归获取父元素的元素实例
Aug 07 Javascript
js获取url页面id,也就是最后的数字文件名
Sep 25 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
在Ubuntu 14.04上部署 PHP 环境及 WordPress
2014/09/02 PHP
thinkPHP中volist标签用法示例
2016/12/06 PHP
PHP模版引擎原理、定义与用法实例
2019/03/29 PHP
对laravel in 查询的使用方法详解
2019/10/09 PHP
Javascript引用指针使用介绍
2012/11/07 Javascript
给artDialog 5.02 增加ajax get功能详细介绍
2012/11/13 Javascript
Javascript级联下拉菜单以及AJAX数据验证核心代码
2013/05/10 Javascript
Get中文乱码IE浏览器Get中文乱码解决方案
2013/12/26 Javascript
jQuery弹出框代码封装DialogHelper
2015/01/30 Javascript
jquery使用slideDown实现模块缓慢拉出效果的方法
2015/03/27 Javascript
jquery序列化方法实例分析
2015/06/10 Javascript
jquery-tips悬浮提示插件分享
2015/07/31 Javascript
jquery京东商城双11焦点图多图广告特效代码分享
2015/09/06 Javascript
jquery中ajax处理跨域的三大方式
2016/01/05 Javascript
Javascript之String对象详解
2016/06/08 Javascript
前端js弹出框组件使用方法
2020/08/24 Javascript
js实现图片加载淡入淡出效果
2017/04/07 Javascript
纯JS实现图片验证码功能并兼容IE6-8(推荐)
2017/04/19 Javascript
Angular 4.0学习教程之架构详解
2017/09/12 Javascript
基于vue cli重构多页面脚手架过程详解
2018/01/23 Javascript
vue实现pdf导出解决生成canvas模糊等问题(推荐)
2018/10/18 Javascript
Vue混入mixins滚动触底的方法
2019/11/22 Javascript
Python实现读取txt文件并画三维图简单代码示例
2017/12/09 Python
python3.8与pyinstaller冲突问题的快速解决方法
2020/01/16 Python
tensorflow通过模型文件,使用tensorboard查看其模型图Graph方式
2020/01/23 Python
python3 字符串知识点学习笔记
2020/02/08 Python
使用Python FastAPI构建Web服务的实现
2020/06/08 Python
python属于跨平台语言码
2020/06/09 Python
基于Python的一个自动录入表格的小程序
2020/08/05 Python
全球性的在线购物网站:Zapals
2017/03/22 全球购物
人力资源主管岗位职责
2014/01/29 职场文书
教师学习培训邀请函
2014/02/04 职场文书
机械系毕业生求职信
2014/05/28 职场文书
运动会广播稿200字
2014/10/18 职场文书
2014年质检员工作总结
2014/11/18 职场文书
检讨书模板大全
2015/05/07 职场文书