背景
最近睡前习惯翻会书,最近在重温《JavaScript权威指南》这本书。这本书,文字小,内容多。两年了,我才翻到第十章。因为书太厚,平时都充当电脑支架。
今天看文章目录的时候,发现一个章节叫「元编程」。我看书中的解释
常规编程是写代码去操作数据,元编程则是写代码去操作其他代码。
我是这样理解的,用代码去操作代码就意味着被操作的代码有可以被扩展的特性,比如可写、可枚举等。而这些特性,可以帮助实现一些特别的功能。利用特性去编写功能的过程可以被归结为「元编程」。比如编写可重用的库等。
元编程特性
属性的三个特性
可写、可枚举、可配置,这三个特性前两个我晓得,但是最后一个我没啥印象了。来看书里对三个特性的解释
可写(writable)特性指定是否可以修改属性的值。
可枚举(enumerable)特性指定是否可以通过for/in循环和Object.keys()方法枚举属性。
可配置(configurable)特性指定是否可以删除属性,以及是否可以修改属性的特性。
可以使用Object的getOwnPropertyDescriptor方法,帮助获取对象上某个属性的属性描述符。如果不存在则会返回undefined。
letobj= { name: '张三', age: 17, }; // name属性存在console.log(Object.getOwnPropertyDescriptor(obj, 'name')); // => { value: '张三', writable: true, enumerable: true, configurable: true }// interest属性不存在console.log(Object.getOwnPropertyDescriptor(obj, 'interest')); // => undefined
示例代码中不存在interest属性,但是也不是不可以有。Object.defineProperty()方法可以帮助对象创建一个指定了特性的属性。
Object.defineProperty(obj, 'interest', { value: '华夏美食、国漫、古风重度爱好者', writable: true, enumerable: true, configurable: true, }); console.log(obj.interest); // => 华夏美食、国漫、古风重度爱好者
Proxy
使用Proxy可以修改JavaScript对象的基础行为,并创建具体普通对象无法企及能力的代理对象。
代理对象可以从目标对象和处理器对象上获取它们的行为,进行特定处理;也可以只拦截对象操作,但仍然把操作委托给目标对象。
前一种方式可以帮助创建一个只读器,所有试图写入的操作都会抛出异常。
functionreadonlyProxy(p) { functionreadonly() { thrownewTypeError('该方法是只读方法'); } returnnewProxy(p, { set: readonly, defineProperty: readonly, deleteProperty: readonly, setPrototypeOf: readonly, }); } letobj= { name: '张三', age: 17, }; letw=readonlyProxy(obj); // 可以正常读取属性console.log(w.name); // => 张三// 删除报错deletew.age; // => TypeError: 该方法是只读方法// 写入报错w.interest='华夏美食、国漫、古风重度爱好者'; // => TypeError: 该方法是只读方法
后一种方式可以用于打印日志。这个功能占了满满三页,太长了,容我再学习一下。
模版标签
位于反引号之间的字符串被称为“模版字面量”。可以把定义使用标签化模版字面的标签函数看成是元编程。
比如String.raw``,可以返回反引号中未经处理的文本。
letlen=String.raw`\n`.length; console.log(len); // => 2:一个反斜杠字符和一个字母n
虽然不知道实际使用场景,但是多学一点总有好处,保不齐将来可能会用到。
总结
温故果然可以知新。学习完元编程的章节,已经没有最初看到它的时候那么困惑了,感觉有些难读懂的源代码有望读懂了。而且打印日志的功能,我准备再研究研究,我有预感,肯定能有用。
《JavaScript权威指南》真是一本宝藏图书,看来有必要把其他章节都学习一下。
今天也特别有收获的一天。