手机版

有趣的深度分析javascript中的反核心化

时间:2021-10-06 来源:互联网 编辑:宝哥软件园 浏览:

写在前面的话:国内对前端的研究在某些方面并不逊色于国外。虽然这篇文章不太好理解,但我很欣赏深入研究的精神!反核心化的话题来自javascript之父Brendan Eich去年的一条推文。最近几天研究了一下,觉得很有意思。分享一下。先忘记它的名字,看看它能做什么。

不要低估这个功能。想象一下,当我们编写一个库时,我们经常会编写这样的代码。以webQQ的Jx库为例。

我们想要的是从Array的原型链中借用一些函数。没有必要显式地构造一个新函数来改变它的参数并重新操作。如果说用不切法明显更优雅精彩,那就是这样的:

有许多有趣和方便的事情要做。

甚至调用和应用方法也不是不可修改的,函数被用作普通数据。这使得在javascript中调用函数的方法更像它的前身方案。当函数名本身是变量时,这个调用方法特别方便。方案中的调用函数类似于:

它可以用javascript写得非常接近。

再看看jquery库,因为jquery对象(也就是$()创建的对象)是一个冒充对象的伪数组,它有length属性,可以通过下标找到对应的元素。当需要向jquery对象添加成员时,伪代码大概是:

如果你使用uncurrying,你可以

借用了数组对象的推送功能,让引擎自动管理多个组成员和长度属性,并且可以一劳永逸地借用所有需要的功能。测试代码:

总的来说,使用反绕技术,你可以让任何对象拥有原生对象。如果你还是对这里不感兴趣,那你可以做点别的。接下来,我们一步一步来看原理和实现。在我们知道反拍马屁这个奇怪的名字之前,我们必须先了解拍马屁。维基百科上的定义:讨好;也称为部分求值,它是一种将接受多个参数的函数转换为接受单个参数的函数,并返回接受剩余参数的新函数并返回结果的技术。一般来说,currying有点类似于买房时的分期付款方式,先给一部分首付(一部分参数),还一个存折(还一个函数),剩下的参数酌情给与评估。让我们看看我们用过的货币。在绑定上下文时,我们经常会实现一个Function.prototype.bind函数。

高阶函数是实现currying的基础,所谓高阶函数至少满足这两个特点:1、函数可以作为参数传递,2、函数可以作为返回值。在Javascript设计之初,就参考了scheme语言的许多特性。Scheme是函数语言鼻祖lisp的两种方言之一,所以javascript也有函数语言的一些特点,包括高阶函数、闭包、lambda表达式等等。当javascript中的一个函数返回到另一个函数时,会形成一个闭包,第一个操作的参数可以保存在闭包中。我们用这个想法写一个通用的currying函数。

我们同意当参数传入时,电流将继续,只有当参数为空时,评估才会开始。假设我们实现了一个计算每月费用的函数,我们会在每天结束前记录今天花了多少钱,但我们只关心月底的费用总额,所以不需要每天都计算。

使用currying函数,您可以将计算一起延迟到最后一分钟。优点不言而喻。在很多场合下,可以避免不必要的计算,节省性能。也是实现惰性评价的一种方案。好了,现在我们可以进入正题了。课程是提前填写一些参数。反课程是延迟固定参数或此上下文作为未来参数的传输。其实就是做这样的事情。obj.foo(arg1) //foo最初只是obj上的一个函数。就像push最初在Array.prototype上被转换成这种形式一样,foo(obj,arg1) //与我们给出的第一个例子相同。正在转换[]。推入推入([])就像原来连接电视插头的插座。把它拿走。在Ecma上Array和String的每个原型方法之后,都有这样一段话,比如push:注意push函数是国际通用的;它不要求它的这个值是一个数组对象。因此,它可以作为一种方法转移到其他类型的对象中。Why is concat函数是否可以应用. javascript是这样设计的吗?让我们回顾一下动态语言中重要的鸭子类型。讲个故事:很久以前,有个皇帝喜欢听鸭子呱呱地叫,于是他召集大臣们成立了一个1000只鸭子的合唱团。部长抓了全国所有的鸭子,但最后他还是缺一只。有一天,一只志愿鸡终于来了。这只鸡说它也会呱呱叫。在这个故事的背景下,它会呱呱叫。后来故事的发展很明显,鸡被混进了鸭的合唱中。皇帝只想听到呱呱的叫声。他不在乎你是鸭子还是鸡。这就是鸭型的概念。在javascript中,许多函数并不检测对象的类型,而只关心这些对象能做什么。数组构造函数和字符串构造函数的原型方法是专门设计为鸭式的。这些方法不检查此的数据类型。这就是为什么参数可以以数组的形式调用push方法。看看Array.prototype.push在v8引擎中的代码:复制代码如下:函数arraypush(){ var n=to _ uint 32(this。长度);var m=% _ ArgumentsLength();for(var I=0;我是;I){ this[I n]=% _ Arguments(I);//属性复制this . length=n m;//修改长度返回this.length}}如您所见,ArrayPush方法并不限制这种类型,因此理论上任何对象都可以作为访问者传递到ArrayPush中。我们只需要解决一个问题,如何让一个对象以一般的方式冒充一个数组对象。真正的实现代码其实很简单:

虽然这段代码很短,但是第一次理解还是有点费力。让我们以push为例,看看它发生了什么。复制的代码如下: var Push=array . prototype . Push . uncrurring();推(obj,' first ');

版权声明:有趣的深度分析javascript中的反核心化是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。