鱼C论坛

 找回密码
 立即注册
查看: 2908|回复: 10

[庖丁解牛] 0 1 5 8 ★ 小王子与Js教主 |【By-老刘】

[复制链接]
发表于 2017-7-28 10:17:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 不二如是 于 2017-7-28 10:25 编辑

推荐阅读:

0 1 5 7 ★ 寥寥数行代码玩透“hoist”|【高级玩家必看】

0 1 3 2 ★ 小心! 这里有'隐式的强制转换'!!! | 【握草,Boom~~~】

0 1 3 3 ★ 得“闭包”者得天下! | 【精英版】




7281aa0212eaaad548d3e5a9da73327e.png


登场人物名:

小兰 : lambda

邱大教主:阿隆佐.丘齐(Alonzo Church)  Lambda演算发明人







  • 拜函数教


  • Java 小王子在 JavaScript 王国待了也有一段时间了。

    这里虽然不像 Java 帝国那样规范严苛,但也因此千奇百怪,五光十色。

    要说小王子最喜欢待的地方,那还是人来人往的 JSON 酒馆,不仅有上好的酒菜,还有机会认识到各式各样的人。

    这不,一来二去他已经和上回认识的眼镜官员成了朋友,甚至私底下还称兄道弟的

    这一天小王子又和眼镜大哥一起约来吃酒。

    才寒暄了几句,筷子还没动,酒馆门口就发生了一点骚动

    只见来了一位看起来像是教书先生的精瘦男子,旁边还有些随从。

    “...... 大哥,这人什么来头,气度不凡啊。”

    小王子悄声向旁边的眼镜官员问到。

    “哈哈,他是拜函数教的邱大教主,最近他们教派的信众激增啊,真是风水轮流转。”


    “函数式?“

    以前随父亲经商途中是听说过他们的事情,好像非常古老而且高深莫测啊。

    据说只有学者和虔诚的教徒才会加入他们,怎么最近也接收新人了?

    “小弟果然是见多识广,不错,在很久以前的确是这样,不过为何有大批新教徒这种事情也不在我的管辖范围内啊,所以也不太清楚。但是毕竟我是本国语言规范审查官,还是与他打过一些交道。不妨我们邀请他来一起喝酒,你亲自问他。”


    小王子本来听到眼镜大哥也不了解情况正有些失望。

    突然得知可以直接面对面打探对方的底细,顿时兴奋了起来。

    “那太好了!”

    “这不是眼镜老弟么,别来无恙啊。”

    “主教兄,甚好甚好,要不这顿我请?小二!”


    饭菜上桌,互相客套了几句之后,话题就开始了。

    “主教兄,这是我最近认识的朋友,年纪轻轻就周游四方,他有些事情要问你。”


    “哦?”函数式主教把目光放了过来,“有何见教?”

    “久闻贵教派向来神秘,为何最近有如此多的新教徒加入呢?”

    “哈,这个嘛 ... 现在的年轻人都不喜欢条条框框,本教向来以简洁强大著称,自然就受欢迎了。”

    小王子心想,这个教主倒也是有话直说、自卖自夸。

    [b]
    不过难道没了面向对象这种强大的武器,他还能变出怎么样的花儿来?
    [/b]


    “那还敢请教教主大人,依你看要怎么实现 Animal, Cat, Dog 这些对象呢?”

    想了一会儿,小王子认为不如直接发问。

    “这个嘛,本教派并无对象这种说法,不过如果你愿意,也可以构造一个对象出来,只需要......”

    “我们拜函数教不用对象~”


    还没等着主教说完,旁边的妹子突然发话了。

    “哦,小兰,你来说吧。”

    这位被叫做小兰的少女像是主教的助手,看起来深得主教信任。

    “嘻嘻,教主大人说的太复杂了,其实实现你说的那些根本不用什么对象。”

    “哦?那该怎么做?”

    小王子顿时来了兴趣。

  • 一等公民:函数


  • “你想啊,搞出来这些猫啊狗啊的,不就是想让他们都可以吃东西么?干嘛要封装到一个对象中,太压抑了”

    640.png


    哦!

    Java 小王子恍然大悟,在自己的Java帝国,法律非常严格, 类和对象才是一等公民

    函数是不可能独立存在的, 你即使是想输出一个简单的hello world , 也必须写一个类。

    在类中写一个方法 , 在这个方法中才能输出hello world 。

    在这里函数已经翻身做主人,成为了一等公民

    再也不用困在对象的牢笼中,声明后就可以直接使用。

    “也就是说,猫、狗都可以直接拿来调用咯?”

    763987aca16292778b4b74594e643c88.png


    “是的呢~ 不止是猫、狗,连人都能作为参数调用呢, 只要一个对象有name这个属性就行啊

    小兰的脸上还是一样的笑容。

    640-1.png


    长期在一个强类型的语言中生活,小王子对这种有点“变态”的灵活性还真不习惯。

    他说:

    “在Java帝国,方法的参数都有确定的类型,如果你的方法写错了,IDE就能自动帮你检测, 减少了很多错误,现在可就没这种福利了。”

    “有得必有失嘛”

    小兰笑道

    “你可以多写一点单元测试来保证正确性啊”

    “既然函数是一等公民, 我相信它不止这点能耐吧?“

    “那是自然, 我们这里的函数还可以作为参数传递给另外一个函数呢!”

    640-2.png


    小王子突然想到父王给自己讲过,要在Java8中引入函数式编程。

    可以把一个所谓的lambada 表达式传递给另外一个函数, 省去了创建类或匿名类的开销。

    但是宫廷老师偷偷地告诉过自己:

    “那只是半吊子的函数式编程,每个lambda表达式其实还得和一个函数接口相匹配, JDK在背后做了类型的推断”


    函数既然能作为参数,我猜肯定也能作为返回值吧?”

    小王子觉得拜函数教的邱大教主在场, 这个天真活泼的小兰好像不敢给自己透露太多, 只好主动发问。

    “你这个外乡人很聪明嘛, 估计有不少编程基础吧?”

    小兰又展示了一段代码:

    640.jpeg


    果然和自己的猜想一致!


    作为皇族,小王子确实非常聪明,他很快就想到了另外一个问题:

    “如果内部的eat函数访问了外部函数的变量会发生什么状况?”


      640-3.png


    按照我们Java 帝国的理论, 函数在被调用的时候是以栈帧的方式被压入栈中的。

    函数的局部变量也在栈帧当中, 当这个函数返回,对应的栈帧就会被清除,局部变量自然也不可用了。

    现在这个eat函数还能再使用createEatFunction()函数的desc这个变量吗?

    或者在调用它的时候会使用外边的全局desc 变量?

    从而输出 "dog 正在吃东西”?

    函数作为返回值看起来很美, 但细节着实让人费解啊?

  • 闭包


  • 看到小王子像上次一样又“卡”住发呆了, 眼镜官员笑着对主教和小兰说:

    这小子肯定又在深思了。


    小兰说:

    “这个外乡人确实不一般,思考很深入,让他的CPU再运转一会儿吧”

    小王子没有找到答案,从思考中回来,看到大家都盯着自己看。

    有点不好意思, 把疑惑给大家说了。  

    “外乡人,Java 把你毒害得不浅, 我看你资质不错,不如忘掉Java 那丑陋的模型, 加入到我们拜函数教来吧。 将来你继承我的位置也未可知啊!”

    邱大教主看了小兰一眼,意味深长地说。

    小兰接口说:

    “还是先解释下你的疑惑吧, 你那段代码的输出应该是‘dog is eating’ , 而不是 ‘dog 正在吃东西’”

    小王子说:

    “这我猜到了, 我就是不理解一个函数(createEatFunction)都执行完了, 为什么它的变量(desc)还能被 后面执行的函数(eat)来使用。”

    “要不说你的java毒中的很深啊, 你换个角度想想,局部变量在函数执行完以后还可以被访问。那它肯定不能存在于你说的那个什么java栈帧中。 小兰说。

    “那它放在那里?”

    “在JavaScript 当中,有个作用域链(scope chain)的东西,它定义了一个函数激活执行的时候去哪儿找变量的值,  比如eat函数的作用域链是这样的:”

      640-4.png
      此图只是示意图,并不严谨,例如没有表达出Activation object, Variable Object等概念


    小王子看着这个图,马上就明白了,这个eat函数没有定义desc 这个变量。

    所以就沿着链去查找, 在createEatFunction作用域去查找。

    如果还找不到,就到global 作用域中查找......

    这个例子中,在createEatFunction的作用域中有定义,于是就直接使用了。

    “可是,createEatFunction 已经执行完了, 难道它的desc 变量不删除吗? ”

    小王子不服气地说 。

    “那肯定不能删除喽”  

    小兰说  

    “这里和你熟悉的java 有个重要的不同, 当你执行creatEatFunction的时候, eat函数才会被创建出来,此时eat函数就会把外部函数的作用域链记录下来(其中包含desc=' is eating'),以便执行时使用”

    “哦,这个作用域是在函数创建时刻发生关联的,而不是运行时刻”

    “没错, 这叫做静态作用域(static scope),或者叫词法作用域(lexical scope)。当eat函数被激活执行,就可以在createEatFuncction中找到desc的值,而不是在全局中找到desc的值。 ”

    小兰接着说。

    “我再给你看个例子, 你就理解这个静态作用域了”

    640-5.png


    小王子说:

    “这段代码的输出应该是2 啊, 还有什么可说的,哦,不对不对,应该输出1, 静态作用域!   函数foo在创建的那一刻, 已经确定了它会和包含x=1的全局作用域关联 , 所以在运行的时候也只会从全局作用域查找,而不是从bar 函数的作用域中找x ”

    “看来你已经Get到了, 这个静态作用域是实现闭包的一个必需条件, 你听说过闭包吧?”

    小王子说:

    “我听父王说过,但是不知道怎么回事....”

    小王子说漏了嘴,赶紧打住。

    小兰像没有听到一样,继续讲闭包:

    “闭包在JavaScript当中就是一个函数和以静态方式存储的父作用域的一个集合体,通过这个集合体,一个函数就可以访问外部函数的变量了。 ”

    “所以eat函数就可以访问外部函数的变量了!  闭包这个名称有点古怪,不过背后的概念还是比较清晰的”

    小王子赶紧说。

  • 尾声


  • “咳咳,小莱你够了。客人都被你吓到了。”

    这时,在旁边默默看着的邱大教主说话了。

    经过这一番交谈,小王子震惊于函数式的独特之处,尤其是和Java帝国的不同。

    不过毕竟是皇族,阅历丰富,他还是悟出了一点门道。

    “我大概明白了一点,由于 JavaScript 是动态类型,其实无论是函数还是对象,在这里都可以做为一个值来传递。函数式里面偏向对值直接进行处理,通过对这些值的传递和组合,就可以组装实现更高级的功能。”

    “不错不错,我看你这位朋友的来头可不一般啊,新加入的信徒大多都经过漫长的适应期才能理解,他却立即悟出这些道理来。”

    邱大教主对小王子赞赏有加,或许以他的智慧已经识破了小王子的身份。

    “不不不,还是因为小兰妹妹讲的好啊。”

    小王子脸红的说道。

    “这还不是多亏了我们的原型才能自由灵活的实现各种编程范式么。”


    眼镜大哥也参合了起来。

    “哈哈哈,你又在自夸了。”

    “来,说了这么多 eat,不说了,吃菜吃菜~”

    游客,如果您要查看本帖隐藏内容请回复


评分

参与人数 2荣誉 +10 鱼币 +10 贡献 +6 收起 理由
睦ちゃん她爹 + 5 + 5 + 3
542624047 + 5 + 5 + 3 很喜欢这种形式,趣味大增,又蕴含丰富的知.

查看全部评分

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2019-6-2 17:25:23 | 显示全部楼层
我操,Java还有这限制!一定要创建object?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2019-7-11 17:00:07 | 显示全部楼层
看看
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-2-28 11:20:58 | 显示全部楼层
问下这个老刘是谁?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-3-2 14:18:16 | 显示全部楼层
666
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-6-13 16:35:35 | 显示全部楼层
0
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2021-10-15 16:34:21 | 显示全部楼层
·1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-10-6 20:40:24 | 显示全部楼层
1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-10-20 13:40:54 | 显示全部楼层
謝謝提供資料
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-9-13 14:24:31 | 显示全部楼层
啊啊啊感觉没太看懂。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-10-31 16:45:19 | 显示全部楼层
1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-21 21:47

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表