紧接上回,伴随着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++}
}
再看一下Proxy
和Reflect
对象
自ES6开始,JavaScript获得了
Proxy
和Reflect
对象的支持,允许你拦截某些操作并实现自定义行为;这样我们不就可以使用这两个对象,更简单的编写出拥有能够读取、分析或者转换其他程序能力,甚至是在运行时修改程序自身的代码;
看完上面的例子我们对元编程应该有了一个模糊的认识,接下来,来看一下,元编程和普通编程的不同,元编程主要的几点特性,看看这种编程技术在关注什么?解决什么?有什么优缺点?
元编程和普通编程的不同
普通编程:一般代码的操作对象是数据,输入数据输出数据,程序运行是动态的,但程序本身是静态的
元编程:操作对象是代码,将程序作为数据来对待,程序运行是动态的,但程序本身也是动态的
- 元语言非目标语言–侧重代码内容的生成,并不关注目标语言代码的编译和执行,也可以称之为产生式生成或代码生成技术
- 元语言即目标语言–主要靠反射机制,允许程序在运行时改变自身的行为
元编程的意义?
元编程旨在用更灵活的代码来适应快速变化的需求,同时保证性能;扩展语言的普通机制来提供额外的能力
元编程的优缺点?
-
优点提升程序性能提成程序的理解能力提升程序的复用能力* 缺点如果编程的本质是抽象,那么元编程就是更高层次的抽象,那元编程这样代码的可读性,可维护性就大大降低了,有些代码甚至会像看天书一样。让代码去生成代码,去修改自己,如果使用不当,在安全性上,存在很大的隐患### JavaScript中的元编程
-
修改默认的语言行为:
Object.defineProperty()
、Proxy
* 反射:Reflect
* 生成代码:`eval````let str = “function sayHello(){console.log(‘hello’)}”;eval(str);sayHello();// 输出hello ```### 总结 -
还是先理解记住一下相关概念,元编程是一种编程技术,编写出来的计算机程序能够将其他程序作为数据来处理。意味着可以编写出能够读取、分析或者转换其他程序的能力,甚至是在运行时修改程序自身。
-
ES6新增了对
Reflect
和Proxy
对象的支持,使得我们能够便捷地进行元编程 -
如果对
Reflect
和Proxy
对象还不是很了解,看看前面的那片文章 -
如果你看到这里了,烦请大佬点个赞,鼓励小弟学习,不胜感激,谢谢
最后
整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。
有需要的小伙伴,可以点击下方卡片领取,无偿分享