javascript元编程之反射

        上一篇和大家聊了聊元编程的代码生成,这一次和各位聊聊反射吧。

        看过我上一篇博文的朋友已经对元编程有个大概的了解了,“用代码编写代码”,并实践了怎么动态生成代码,那么反射又是怎么回事呢?

反射就是,可以在运行时检查或修改代码结构,从而改变代码的表现形式。

                                                                                                      ——前端装逼架构师 Yubble

        注意了同学,之前是生成,现在是’查‘、’改‘。

        大致了解了反射的概念,我们再来详细了解下反射的三个分支:

            1、自省(Introspection):代码能够自我检查、访问内部属性,我们可以据此获得代码的底层信息。

            2、自我修改(Self-Modification):顾名思义,代码可以修改自身。

            3、调解(Intercession):在元编程中,调解的概念类似于包装(wrapping)、捕获(trapping)、拦截(intercepting)。

        这几个专业术语看起来很高大上哈,但是我们在以前的开发过程中经常会用到,只是我们当时不知道罢了,下面上代码。

        例子1:自省——自我检查,访问内部属性

        在我们日常工作时编码访问一个对象内部信息,以及检查内容时,这种方法就称为自省,是不是感觉起了个比较中二的名字。

        例子2:自我修改——代码可修改自身

        这个也就没什么可说的了,简单的赋值实现

        例子3:调解——包装、捕获、拦截

        js中对调解最有力的表现方式就是defineProperty了,它重新定义了对一个对象属性的使用,搭配着get、set方法又充分的诠释了捕获与拦截的特性。


        相信写到这里,各位客官都有些疑惑了吧,“既然之前的语法都支持反射,为什么还会出现一个Reflect API?”,原因我归纳了以下几点:

        1、将所有的反射操作都集中在一个命名空间中。我们如果百度的话,就会发现Reflect支持13种反射操作,其中大多都已经在Object、Function对象中实现过,但是Reflect对它们做了个整合,且未来会只支持Reflect API这种方式。

        2、让返回结果更加规范合理。比方说之前在Object.defineProperty()中给对象做调解时,如果被控制的object是已经被Object.freeze()冻结过的,在Object.defineProperty()里操作set方法则会报错,此时如果不想影响到整条进程则需要使用try {} catch() {}来包裹。而Reflect.defineProperty()则是可以用if() else {}来做报错判断,巴适滴很。

        3、让函数代替操作符。函数依旧是我们在js世界中的一等公民,我们之前用于操作对象内部的操作符可以用它完全替换掉。例如用 Reflect.has() 代替 in,用 Reflect.deleteProperty() 代替 delete,用 Reflect.constructor() 代替 new。这些命令符虽说使用起来确实效果不差,但是如果想要复用这些能力的话,还是需要将其封装为一个函数,所以Reflect API为我们提供了这个函数。

        4、帮助代理实现反射(Proxy)。这一块是目前Reflect使用最频繁的场景,提到Proxy我们也要捎带啰嗦两句,介于Vue2.0与3.0的实现原理,所以我们经常会把Object.defineProperty与Proxy相提并论,但是在我看来他们的定义差别还是很大的,从字面翻译上,一个是给对象中某一个属性做属性定义,一个是给某个对象做代理。虽然他们都存在set、get这些拦截方法,且符合反射中调解这个定义,但是Object.defineProperty更注重对象中某一个属性的可操作性(可读、可写、可便利),Proxy则是对整个对象的拦截并完成反射。

        为什么说Reflect可以协助Proxy完成反射呢?因为在Proxy第二个参数handle中包含的拦截方法,Reflect API都有对应的实现。请看代码实现:

        其实这第三个参数reciver才是使用Reflect.*方法的最关键因素,它的意义是告诉Reflect.get此时调用这个属性的对象或者上下文。我们在用proxy实例时,不免会将这个实例作为其他对象的继承对象,此时的上下文环境应该是调用这个属性的对象,而不是直接写死为trapTarget,用下面这个简单的小例子来说明:

        理论上访问temp.foo时,this应该去temp上去查找,但是由于我们在代理中写死了target[property],那么它只会返回obj对象上的属性,所以这个target也就固定指向了obj对象,这样也就造成了不合理的this指向。具体知识大家可以参考这一篇博文《推荐使用Reflect.get而不是target[key]的原因》

        以上Reflect这个API在元编程——反射中的实现与特点就都交代完了,总结起来的话,就是围绕着对象的访问,检查,拦截,修改表现形式的一种做法。

        提到Proxy就不得不想到Vue3.0的双向绑定,其实它也是遵循着元编程的思路去实现,而它的元数据则是被代理的virtual Dom,通过对virtual Dom的代理进行反射操作,之后如果有时间,我会整理下Vue3.0中具体使用到元编程——反射的案例。这里给大家推荐一本书《Vue.js设计与实现》,在下有幸与它的作者霍春阳做过同事,这本书内容丰富,对我们技术视野的提升也是很有帮助的。


        终于把元编程全部梳理完了,也算是对自己有个交代。前段时间整个人有点颓,也找了不少小伙伴喝酒聊天,其中一个朋友说的一句话给我触动很深:“我们本来就处于这种信息高速时代,每天都把自己折磨的很累,难得能有几天能自由支配的时间,如果把这么宝贵的时间都留给焦虑了,那就太遗憾了。

        听完她这句话,我重新定义了一下这段空窗期的安排,上午看自己以前想看的书或电影,下午整理以前没时间整理的知识点,写博文,晚上去拳馆打拳。把节奏慢下来仔细看看生活,发现很多美妙的东西都被自己忽略了。

用我家臭猫子的懒照给各位客官Say goodbye
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容