位置: 编程技术 - 正文

javascript中有趣的反柯里化深入分析(javascript可以制作哪些游戏?)

编辑:rootadmin

写在前面的话:国内对前端的研究在某些方面也不逊色于国外,这篇文章虽然看不太懂,但我很欣赏这种深入研究的精神!

反科里化的话题来自javascript之父Brendan Eich去年的一段twitter. 近几天研究了一下,觉得这个东东非常有意思,分享一下。先忘记它的名字,看下它能做什么.

不要小看这个功能,试想下,我们在写一个库的时候,时常会写这样的代码,拿webQQ的Jx库举例。

我们想要的,其实只是借用Array原型链上的一些函数。并没有必要去显式的构造一个新的函数来改变它们的参数并且重新运算。

如果用uncurrying的方式显然更加优雅和美妙,就像这样:

还能做很多有趣和方便的事情.

甚至还能把call和apply方法都uncurrying,把函数也当作普通数据来使用. 使得javascript中的函数调用方式更像它的前生scheme, 当函数名本身是个变量的时候, 这种调用方法特别方便.

scheme里面调用函数是这样:

javascript里可以写的很接近.

再看看jquery库,由于jquery对象( 即通过$()创建的对象 )是一个对象冒充的伪数组,它有length属性,并且能够通过下标查找对应的元素,当需要给jquery对象添加一个成员时, 伪代码大概是:

如果用uncurrying的话, 就可以

借用了array对象的push函数, 让引擎去自动管理数组成员和length属性.

而且可以一次把需要的函数全部借过来, 一劳永逸. 一段测试代码:

总的来说, 使用uncurrying技术, 可以让任何对象拥有原生对象的方法. 好了,如果到这里依然没有引起你的兴趣,那么你可以去干点别的了。

接下来一步一步来看看原理以及实现。在了解反currying化这个奇怪的名字之前,我们得先搞清楚currying。

维基百科上的定义:科里化( currying ); 又称部分求值,是把接受多个参数的函数变换成接受一个单一参数的函数,并且返回接受余下的参数并且返回结果的新函数的技术。

通俗点讲,currying有点类似买房子时分期付款的方式,先给一部分首付( 一部分参数 ), 返回一个存折( 返回一个函数 ),合适的时候再给余下的参数并且求值计算。

来看看我们都用过的currying, 我们经常在绑定context 的时候实现一个Function.prototype.bind函数.

高阶函数是实现currying的基础, 所谓高阶函数至少满足这2个特性:1,函数可以当作参数传递,2,函数可以作为返回值。

Javascript在设计之初,参考了很多scheme语言的特性。而scheme是函数式语言鼻祖lisp的2大方言之一,所以javascript也拥有一些函数式语言的特性,包括高阶函数,闭包,lambda表达式等。

当javascript中的函数返回另一个函数,此时会形成一个闭包,而在闭包中就可以保存第一次运算的参数,我们用这个思想,来写一个通用的currying函数。

我们约定, 当传入参数时候, 继续currying化, 参数为空时才开始求值.

假设在实现一个计算每月花费的函数, 每天结束前我们都要记录今天花了多少钱, 但我们只关心月底的花费总值, 无需每天都计算一次.

使用currying函数, 便可以延迟到最后一刻才一起计算, 好处不言而喻, 在很多场合可以避免无谓的计算, 节省性能, 也是实现惰性求值的一种方案.

好了,现在才走进正题,

curring是预先填入一些参数.

反curring就是把原来已经固定的参数或者this上下文等当作参数延迟到未来传递.

其实就是搞这样一个事情,将:

obj.foo( arg1 ) //foo本来是只在obj上的函数. 就像push原本只在Array.prototype上

转化成这样的形式

foo( obj, arg1 ) // 跟我们举的第一个例子一样.将[].push转换成push( [] )

就像原本是接在电视插头上的插座,把它拆下来之后,其实也能用来接冰箱。

Ecma上Array和String的每个原型方法后面都有这么一段话,比如push:

NOTE The push function is intentionally generic; it does not require that its this value be an Array object.Therefore it can be transferred to other kinds of objects for use as a method. Whether the concat function can be applied.

Javascript为什么要这样设计, 我们先来复习下动态语言中重要的鸭子类型思想.

说个故事:

很久以前有个皇帝喜欢听鸭子呱呱叫,于是他召集大臣组建一个一千只鸭子的合唱团。大臣把全国的鸭子都抓来了,最后始终还差一只。有天终于来了一只自告奋勇的鸡,这只鸡说它也会呱呱叫,好吧在这个故事的设定里,它确实会呱呱叫。 后来故事的发展很明显,这只鸡混到了鸭子的合唱团中。— 皇帝只是想听呱呱叫,他才不在乎你是鸭子还是鸡呢。

这个就是鸭子类型的概念,在javascript里面,很多函数都不做对象的类型检测,而是只关心这些对象能做什么。

Array构造器和String构造器的prototype上的方法就被特意设计成了鸭子类型。这些方法不对this的数据类型做任何校验。这也就是为什么arguments能冒充array调用push方法.

看下v8引擎里面Array.prototype.push的代码:可以看到,ArrayPush方法没有对this的类型做任何显示的限制,所以理论上任何对象都可以被传入ArrayPush这个访问者。

我们需要解决的只剩下一个问题, 如何通过一种通用的方式来使得一个对象可以冒充array对象。

真正的实现代码其实很简单:

这段代码虽然很短, 初次理解的时候还是有点费力. 我们拿push的例子看看它发生了什么.

推荐整理分享javascript中有趣的反柯里化深入分析(javascript可以制作哪些游戏?),希望有所帮助,仅作参考,欢迎阅读内容。

javascript中有趣的反柯里化深入分析(javascript可以制作哪些游戏?)

文章相关热门搜索词:js有哪些有意思的编程,javascript可以制作哪些游戏?,js有趣的功能,javascript有什么,javascript ul,javascript的游戏,js有哪些有意思的编程,js可以做什么有趣的东西,内容如对您有帮助,希望把文章链接给更多的朋友!

javascript SpiderMonkey中的函数序列化如何进行 在Javascript中,函数可以很容易的被序列化(字符串化),也就是得到函数的源码.但其实这个操作的内部实现(引擎实现)并不是你想象的那么简单.SpiderMonkey中

php图像生成函数之间的区别分析 新手对php图像生成函数imagecreatetruecolor()和imagecreate()又不解之处,首先来看看官方对这两个函数的解释:resourceimagecreatetruecolor(int$x_size,int$y_size)返回一

javascrpt绑定事件之匿名函数无法解除绑定问题 经常听到有人说,匿名函数绑定事件不好控制啊,无法解除绑定啊等等等等,一直很奇怪谁说的不能解除绑定。下面来实现click事件2次后,自动解除绑

标签: javascript可以制作哪些游戏?

本文链接地址:https://www.jiuchutong.com/biancheng/379157.html 转载请保留说明!

上一篇:关于javascript中的typeof和instanceof介绍(javascript语言中,以下关于array)

下一篇:javascript SpiderMonkey中的函数序列化如何进行

  • 增值税核算办法
  • 综合保税区是什么意思,举个例子
  • 增值税税控系统技术维护费怎么做账
  • 建筑业的账务处理
  • 单位出租不动产印花税
  • 企业所得税期初资产总额怎么填写
  • 补提盈余公积的分录
  • 员工工资占公司收入比例怎么算
  • 利润表研发费用包括哪些内容
  • 法定盈余公积和法定公积金一样吗
  • 计提物业费会计分录
  • 印花税不计提是当月交当月吗
  • 开发成本月末如何处理
  • 产权转移书据印花税计入什么科目
  • 出口发票金额和备注了差了1分钱
  • 境内企业转让境外股权税收
  • 销项负数发票怎么冲减成本
  • 企业发工资哪些需要缴个人所得税?
  • 开专用发票可以不写单位与型号么?
  • 医院开发票需要税号吗
  • 开通税种需要带发票吗
  • 进口采购交的增值税
  • 产值等于营业额吗
  • 滴滴开的发票能否抵扣进项税
  • 税控盘提示未抄报税
  • 网上申报城建税及附加怎么操作
  • 失控发票如何转出
  • 无法偿还的应付款项予以转账
  • 企业补充流动资金具体用途
  • 住房公积金个税抵扣标准
  • php数组根据值排序
  • 工程决算审计费收费标准
  • 哪些项目容易漏缴个人所得税?
  • 供热企业有哪些
  • 处理固定资产怎么交税
  • 增值税纳税人如何界定
  • 支付宝手机网站支付不风控
  • python怎么安装lxml库
  • ps怎么弄树
  • ps中文字复制粘贴
  • 以固定资产抵债发生的固定资产
  • 多付款退回怎样写说明
  • 营改增后自建厂房抵扣
  • 税控盘维护费每年都要交吗
  • 个税 全年累计
  • sqlserver2008不存在或拒绝访问怎么办
  • 代开专票上的税额比电子缴款凭证上的税额少怎么调整?
  • 公积金贷方有余额如何做调整分录
  • 现金支票最少多少起提
  • 电子承兑过期了
  • 电商刷单返现如何做账务处理合适?
  • 设备安装成本怎么结转
  • 土地无形资产要摊销吗
  • 其他收入属于什么收入
  • 商业零售企业商品进销差价
  • freebsd 升级
  • win7无法安装谷歌
  • Linux(CentOS)用split命令分割文件的方法
  • win8怎么打开管理员命令提示符
  • 个人pc用户免费下载软件
  • Cocos2dx CrazyTetris 双线伪裁剪算面积 对于判断消除的思考(二)
  • Android游戏开发教程
  • CCKiller:Linux轻量级CC攻击防御工具,秒级检查、自动拉黑和释放
  • shell脚本读取ini文件
  • 编写折半查找的程序
  • shell脚本 -ne 0
  • 基于python的游戏
  • android 按键
  • javascript刷新页面的几种方法
  • JavaScript中的变量名不区分大小写
  • android四大组件面试
  • jquery返回顶部代码
  • python的例子
  • jquery ui和jquery easy ui
  • Jquery和BigFileUpload实现大文件上传及进度条显示
  • 四川国税发票真伪查询
  • 税控盘登陆失败
  • 两江新区钓鱼地方
  • 山东省准生证是什么样子图片
  • 公司残疾员工是什么待遇
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设