likes
comments
collection
share

JavaScript中的元编程

作者站长头像
站长
· 阅读数 66

紧接上回,伴随着Reflect,Proxy降世,为js带来了更便捷的元编程!

什么是元编程?这词第一次听,有点懵,好像有点高级,这不得学一下装....进自己的知识库

概念

元编程是一种编程技术,编写出来的计算机程序能够将其他程序作为数据来处理。意味着可以编写出能够读取、分析或者转换其他程序的能力,甚至是在运行时修改程序自身

往简单意思大概是说:这是一种编程技术,我写的代码能改变其他代码,甚至运行时自己改变自己,哇,这一听怎么有点像人工智能;

看个例子,有个这样的面试题,这个a是什么时,才能输出里面的内容?

// let a = ??? 可使 a 成功输出
if (a == 1 && a == 2 && a == 3) {
    console.log("元编程");
}

那只有a会变化,才有可能输出里面的内容了;比如a初始值是1,调用一次+1,那就可以满足了,要让代码自我修改,即代码修改自身属性或其他底层属性,这不就是刚刚提的元编程中有的么?于刚学了proxy所以使用代理的解法,在a==1的时候会调用a.get,所以可以在get的时候拦截,做一些自定义操作,修改对象的属性值并返回对比所需要的操作

let a = new Proxy({ value: 1 }, {
  get(target, property, receiver) {    
    // 隐式转换会调用Symbol.toPrimitive,这是一个函数
    if (property === Symbol.toPrimitive) {
      // 要返回一個函数用于在对比中转换
      return () => target.value++
    }
  }
})

Symbol.toPrimitive是内置的 symbol 属性(用作函数值),被调用的指定函数值的属性转换为相对应的原始值,它被所有的强类型转换制算法优先调用

注:a==1注意是两个等号,所以a在对比的时候就会触发valueOf()方法,若此方法返回还是对象,就继续调用toString()方法。所以也可以通过重写valueOf() 或者 toString() 方法都可行

let a = {
  i: 1,
  valueOf() {
    return this.i++
  }
}

再看一下ProxyReflect对象

自ES6开始,JavaScript获得了ProxyReflect对象的支持,允许你拦截某些操作并实现自定义行为;这样我们不就可以使用这两个对象,更简单的编写出拥有能够读取、分析或者转换其他程序能力,甚至是在运行时修改程序自身的代码;

看完上面的例子我们对元编程应该有了一个模糊的认识,接下来,来看一下,元编程和普通编程的不同,元编程主要的几点特性,看看这种编程技术在关注什么?解决什么?有什么优缺点?

元编程和普通编程的不同

普通编程:一般代码的操作对象是数据,输入数据输出数据,程序运行是动态的,但程序本身是静态的

元编程:操作对象是代码,将程序作为数据来对待,程序运行是动态的,但程序本身也是动态的

JavaScript中的元编程 编写元程序的语言称之为元语言,被操纵的语言称之为目标语言。根据元语言和目标语言是否相同,我们可以将元编程分为两类:

  • 元语言非目标语言--侧重代码内容的生成,并不关注目标语言代码的编译和执行,也可以称之为产生式生成或代码生成技术
  • 元语言即目标语言--主要靠反射机制,允许程序在运行时改变自身的行为

元编程的意义?

元编程旨在用更灵活的代码来适应快速变化的需求,同时保证性能;扩展语言的普通机制来提供额外的能力

元编程的优缺点?

  • 优点

    提升程序性能

    提成程序的理解能力

    提升程序的复用能力

  • 缺点

    如果编程的本质是抽象,那么元编程就是更高层次的抽象,那元编程这样代码的可读性,可维护性就大大降低了,有些代码甚至会像看天书一样。

    让代码去生成代码,去修改自己,如果使用不当,在安全性上,存在很大的隐患

JavaScript中的元编程

  • 修改默认的语言行为:Object.defineProperty()Proxy

  • 反射:Reflect

  • 生成代码:eval

    let str = "function sayHello(){console.log('hello')}";
    eval(str);
    sayHello();
    
    // 输出
    hello
    

总结

  • 还是先理解记住一下相关概念,元编程是一种编程技术,编写出来的计算机程序能够将其他程序作为数据来处理。意味着可以编写出能够读取、分析或者转换其他程序的能力,甚至是在运行时修改程序自身。
  • ES6新增了对 ReflectProxy 对象的支持,使得我们能够便捷地进行元编程
  • 如果对ReflectProxy 对象还不是很了解,看看前面的那片文章
  • 如果你看到这里了,烦请大佬点个赞,鼓励小弟学习,不胜感激,谢谢
转载自:https://juejin.cn/post/7172006268373368862
评论
请登录