狗万滚球

JavaScript深入浅出第2课:函数是一等公民是什么意

2019-06-28 10:24

  JavaScript函数是一等公民,是什么意思呢?我来与大家探讨一下,抛砖引玉。

  根据维基百科,编程语言中一等公民的概念是由英国计算机学家Christopher Strachey提出来的,时间则早在上个世纪60年代,那个时候还没有个人电脑,没有互联网,没有浏览器,也没有JavaScript。

  大概很多人和我一样,没听说过Christopher Strachey,并且他也只是提出了一等公民的概念,没有给出严格的定义。

  关于一等公民,我找到一个权威的定义,来自于一本书《Programming Language Pragmatics》,这本书是很多大学的程序语言设计的教材。

  也就是说,在编程语言中,一等公民可以作为函数参数,可以作为函数返回值,也可以赋值给变量。

  例如,字符串在几乎所有编程语言中都是一等公民,字符串可以做为函数参数,字符串可以作为函数返回值,字符串也可以赋值给变量。

  对于各种编程语言来说,函数就不一定是一等公民了,比如Java 8之前的版本。

  对于JavaScript来说,函数可以赋值给变量,也可以作为函数参数,还可以作为函数返回值,因此JavaScript中函数是一等公民。

  回调函数(callback)是JavaScript异步编程的基础,其实就是把函数作为函数参数。例如,大家常用的setTimeout函数的第一个参数就是函数:

  JavaScript函数作为函数参数,或者说回调函数,作为实现异步的一种方式,大家都写得多了,其实它还有其他应用场景。

  Array.prototype.sort()在对一些复杂数据结构进行排序时,可以使用自定义的比较函数作为参数:

  这样写看起来没什么大不了的,但是对于JavaScript引擎来说就省事多了,因为它不需要为每一种数据类型去实现一个排序API,它只需要实现一个排序API就够了,至于数组元素大小怎么比较,交给用户去定义,用户如果非得说2大于1,那也不是不可以。

  换句话说,如果Array.prototype.sort()只能实现简单数据(比如Number与String)的排序的话,那它就太弱了,正因为可以使用函数作为参数,使它的功能强大了很多。

  顺便提一下,实现一个Array.prototype.sort(),可不是什么简单的事情,大家可以看看V8是怎样实现数组排序的。

  JavaScript是可以定义匿名函数的,当我们定义有名字的函数时,通常是这样写的:

  在其他的一些First-class function的定义中,还要求函数可以保存到其他数据结构,比如数组和对象中,这一点JavaScript也是支持的。

  函数可以保存到Object中,就意味着函数成为了Object的方法。我在《JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?》中提过,当函数作为Object的方法被调用时,它的this值就是该Object,这1点与Java等面向对象语言是一致的。因此JavaScript在没有Class之前,就在一定程度上是支持面向对象编程的,当然比较弱。

  通常来讲,函数的返回值比较简单,比如数字、字符串、布尔值或者Object。狗万滚球!由于JavaScript函数是第一公民,因此我们也可以在函数中返回函数。

  我猜这个地方有人会抬杠,因为示例代码没有必要这么写,因为有更简单的写法:

  但是这只是一个简单的示例,在一些复杂的实际场景中,在函数返回函数还是很有用的。下面给大家一个简单的示例。

  我们Fundebug在微信小程序BUG监控插件的时候,把不同API的定义拆分在不同的文件,但是这些API需要共享一些全局属性,比如用户的个性化配置。微信小程序是没有全局变量window的,就算是网页端有window其实最好也不要用,会污染全局作用域。这时候该怎么办?给大家看看定义fundebug.test()是怎样定义的吧:

  我们使用了一个外层函数defineTestApi来共享全局配置对象config,函数中定义的testApi函数则通过return返回。

  这里其实也用到了闭包,因为defineTestApi函数执行结束之后,testApi函数仍然可以使用config变量,因此config变量的生命周期超越了defineTestApi函数。关于闭包的详细介绍,我会在这个系列的后续文章中介绍。

  开发者对待每一个技术点,比如闭包,应该保持谦卑,不要觉得这个也没有用,那个也没有用,其实只是你还没遇到使用场景而已。关于这一点,大家可以看看我的博客《聊聊我的第一篇10万+,同时反驳某些评论》。

  函数为第一公民的3个特性我都介绍了,它们确实让JavaScript更加强大,然后呢?JavaScript的骚操作大家见得多了,也不会觉得有什么神奇之处。

  也就是说,函数为第一公民是函数式编程的必要条件。higher-order functions,即高阶函数,就是使用函数作为参数的函数,它在函数式编程中很常见。

  至于什么是函数式编程,不是我一句话能讲清楚的,这可以一直聊到计算机的开山鼻祖图灵。要知后事如何,请听下回分解。

  关于JS,我打算开始写一个系列的博客,大家还有啥不太清楚的地方?不妨留言一下,我可以研究一下,然后再与大家分享一下。也大家欢迎添加我的个人微信(KiwenLau),我是Fundebug的技术负责人,一个对JS又爱又恨的程序员。

  Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java线上应用实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了10亿+错误事件,付费客户有阳光保险、核桃编程、荔枝FM、掌门1对1、狗万滚球。微脉、青团社等众多品牌企业。欢迎大家免费试用!

  一等公民一般来说,如果某程序设计语言中的一个值可以作为参数传递,可以从子程序中返回,可以赋值给变量,就称它为一等公民二等公民可以作为参数传递,但是不能从子程序中返回,也不能赋给变量三等公民它的值连作为...博文来自:Racal

  函数式编程是这几年很受欢迎的一个话题,即使你是一个刚刚踏入职场的新人,如果在面试时能有意无意地透露出你懂那么一点点函数式编程,也会让你的面试官眼前一亮。然而函数式编程并不是一个新的概念,它的源头可以追...博文来自:bitcarmanlee的博客

  前言在前面的分享中,我们聊了Python独特的以鸭子类型为核心的面向对象风格,并通过《流畅的Python》中提供的两个经典示例,介绍了Python中的序列和分片的实现逻辑,并从中抽象出Python是如...博文来自:beacon的专栏

  Python中什么是一等对象first-classobject(第一类对象)?文章目录Python中什么是一等对象first-classobject(第一类对象)?0.参考资料1.定义0.参考资料1....博文来自:团子大圆帅的博客

  1.函数的概念javascript中最关键的概念:函数是第一类对象,或称它们为一等公民。复制代码函数也可以被视为其他任意类型的javascript对象。javascript中函数拥有对象的所有能力,页...博文来自:weixin_33834628的博客

  本文首发自本人博客eczn.github.io/blog/cc2509…以下是原文:写篇文章再谈谈函数和一等公民,因为我发现了些有趣的东西。先前想在自己的函数式方言解释器里实现元组这种数据结构,但是没...博文来自:weixin_33811961的博客

  最近在看λ演算,一开始很迷惑,不就是一堆函数吗,Church为什么要搞个什么λ记法。后来发现,λ记法固然有它的优势(在替换时便于分清替换的是哪个部分,函数还是自变量),但不用它似乎更直观一些。...博文来自:Pope 的废纸篓

  简介在很多传统语言(C/C++/Java/C#等)中,函数都是作为一个二等公民存在,你只能用语言的关键字声明一个函数然后调用它,如果需要把函数作为参数传给另一个函数,或是赋值给一个本地变量,又或是作为...博文来自:杨启盛的博客

  简介在很多传统语言(C/C++/Java/C#等)中,函数都是作为一个二等公民存在,你只能用语言的关键字声明一个函数然后调用它,如果需要把函数作为参数传给另一个函数,或是赋值给一个本地变量,又或是作为...博文来自:yglskfj的专栏

  今天度Swift文档的时候看到了Enumerations,枚举。可以说颠覆了我对枚举的印象,下面将文档中对枚举的介绍记录一下。文档中先解释了枚举的含义:一组有联系的值的公共类型。然后指出了swift中...博文来自:weixin_33758863的博客

  转自:法案聚焦ID:faanjujiao案情介绍小张是一家公司的职员,平时工作兢兢业业,生活也波澜不惊。没想到突然有一天小张被警察带走了,紧接着被没收了所有的随身物......博文来自:电子物证

  NodeJSNodeJS4个特点:异步I/O,事件驱动与回调,单线程事件轮询,跨平台。NodeJS5个大坑:异常处理,嵌套太深,没有Sleep,多线程编程,异步转同步。NodeJS4种提升性能的方法:...博文来自:daviemeng的博客

  之前看到一篇报道,说CNTK最新版本已经支持作为Keras的后端选择之一,但需要单独装定制版的Keras,最近一直关注其动向,可喜的是其代码昨天终于合并到Keras里面了,Keras的作者也不禁赞到,...博文来自:weixin_33872566的博客

  JavaScript世界的一等公民-函数提交新文章 2012年07月11日09:00 简介在很多传统语言(C/C++/Java/C#等)中,函数都是作为一个二等公民存在,你只能用语言的关键字声明一个函...博文来自:diligentcat的专栏

  js中函数是一等公民即js中,函数和其他变量一样,可以把它们存在数组里,当作参数传递,赋值给变量等为什么我们需要纯函数比如现在我们有这段代码functionadd(a,b){returna+b}add...博文来自:goodgirl1991的专栏

  在很多传统语言(C/C++/Java/C#等)中,函数都是作为一个二等公民存在,你只能用语言的关键字声明一个函数然后调用它,如果需要把函数作为参数传给另一个函数,或是赋值给一个本地变量,又或是作为返回...博文来自:天蝎座

  简介在很多传统语言(C/C++/Java/C#等)中,函数都是作为一个二等公民存在,你只能用语言的关键字声明一个函数然后调用它,如果需要把函数作为参数传给另一个函数,或是赋值给一个本地变量,又...博文来自:lgj346435400的专栏

  简介在很多传统语言(C/C++/Java/C#等)中,函数都是作为一个二等公民存在,你只能用语言的关键字声明一个函数然后调用它,如果需要把函数作为参数传给另一个函数,或是赋值给一个本地变量,又或是作为...博文来自:cdestiny的专栏

  三、JavaScript函数妖怪级欢迎来到妖怪级函数授课区,在这里会交给你如何淡定自如地面对老怪。。。3.1Function类在JavaScript运行时中有一个内建的类叫做Function,用fun...博文来自:andybruse

  简介在很多传统语言(C/C++/Java/C#等)中,函数都是作为一个二等公民存在,你只能用语言的关键字声明一个函数然后调用它,如果需要把函数作为参数传给另一个函数,或是赋值给一个本地变量,又或是作为...博文来自:andybruse

  原文链接:javascript世界的一等公民-函数。原文如下:简介在很多传统语言(C/C++/Java/C#等)中,函数都是作为一个二等公民存在,你只能用语言的关键字声明一个函数然后调用它,如果需要把...博文来自:sandeziVIP的专栏

  所谓的一等公民,其实就是普通函数,也就是说,函数其实就是没有什么特殊的,我们可以像对待其他数据类型一样对待函数。1可以把函数赋值给一个变量varfn=function(){};2`也可以把函数存在数组...博文来自:路漫漫其修远也,吾将上下而求索

  拖延症晚期癌,每次都是周日最后一个小时才开始动笔,先鄙视下自己今天要“弹”的是一个有点被说“烂”了的话题,在JavaScript里,函数是一等公民(哇,听起来很高大上吧),而同时在这个函数式编程异常火...博文来自:weixin_34208283的博客

  JavaScript一种直译式脚本语言,是一种动态类型、弱类型、基于原型的语言,内置支持类型。它的解释器被称为JavaScript引擎,为浏览器的一部分,广泛用于客户端的脚本语言,早是在HTML(标准通用标记语言下的一个应用)网页上使用,用来给HTML网页增加动态功能。

  深入浅出MySQL第二版本pdf 。深入浅出,由浅至深的学习MySQL,很适合新手学习

  大家知道ANSI/ISO SQL是公认的关系数据库标准。从SQL标准的符合性来说,MySQL不仅无法跟成熟的商业数据库相比,在开源数据库中也远不是*好的,比如PostgreSQL就是业界公认的ANSI/ISO SQL标准符合性*好的开源数...

  这本书的主题是函数范式,详细介绍了使用JavaScript进行函数式编程,目录包括:一等公民的函数,纯函数的好处,柯里化,代码组合,代码示例,Hindley-Milner 类型签名,特百惠,Monad,Applicative Functo...

  《深入浅出MySQL:数据库开发、优化与管理维护(第2版)》的作者都是MySQL方面的资深DBA。本书不但融入了他们丰富的工作经验和多年的使用心得,还提供了大量来自工作现场的实例,具有很强的实战性和可操作性。 《深入浅出MySQL:数据...

  这是一篇转发的文章,我对他进行了格式化而已,原文出处不详。中国公民身份证编号规则一、身份证号码执行标准:18位身份证标准在国家质量技术监督局于1999年7月1日实施的GB11643-1999《公民身份...博文来自:yingms的专栏

  深入浅出MFC 《深入浅出MFC》分为四大篇。第一篇提出学习MFC程序设计之前的必要基础,包括Widnows程序的基本观念以及C++的高阶议题。“学前基础”是相当主观的认定,但作者是甚于自己的学习经验以及教学经验,其挑选应该颇具说服力。第...

  MySQL++数据库开发、优化与管理维护+第2版+唐汉明.zip.003

  深入浅出MySQL++数据库开发、优化与管理维护 第2版 唐汉明.pdf 带书签。比别家的更便宜,只需更少积分 该资源为深入浅出mysql数据库开发、优化与管理维护的第二版,最新上传,是学习mysql的必备资料 7zip 分卷解压

  FPGA(现场可编程门阵列),即现场可编程门阵列,它是在PAL,GAL,CPLD等可编程器件的基础上进一步发展的产物。它是作为专用集成电路(ASIC)领域中的一种半定制电路而出现的,既解决了定制电路的...博文来自:tyyisyuanyuan的博客

  目录第1章Mysql的安装与配置1.1启动和关闭Mysql服务第2章SQL基础2.1SQL分类2.2常用语句第3章Mysql支持的数据类型3.1数值类型3.2日期时间类型3.3字符串类型第4章Mysq...博文来自:lxxxxxl的博客

  函数式编程vs函数指针函数式一等公民:参数,变量,返回值都可以是函数高阶函数函数-amp;amp;amp;gt;闭包“正统”函数式编程不可变性:不能有状态,只有常量和函数函数只能有一个参数g...博文来自:chao2016的博客

  大家知道ANSI/ISO SQL是公认的关系数据库标准。从SQL标准的符合性来说,MySQL不仅无法跟成熟的商业数据库相比,在开源数据库中也远不是*好的,比如PostgreSQL就是业界公认的ANSI/ISO SQL标准符合性*好的开源数...

  javaScript课件第2课,内容讲解细致,深入浅出,非常适合初学者学习!

  作者 Eric Freeman 译者: 徐阳 / 丁小峰 出版年: 2013.9 代码为官网原版

  JavaScript进阶---许多来源于慕课网教学视频,如侵删。博文来自:编程小菜鸟的笔记

  首先我们来安装python 1、首先进入网站下载:点击打开链接(或自己输入网址),进入之后如下图,选择图中红色圈中区域进行下载。 ...博文来自:陌上行走的博客

  新型的按键扫描程序 不过入式处理器上面我在网上游逛了很久,也看过不少源程序了,没有发现这种按键处理办法的踪迹,所以,我将他共享出来,和广大同僚们共勉。我非常坚信这种按键处理办法的便捷和高效,你可以移...博文来自:phenixyf的专栏

  相信学习编程的同学,或多或少都接触到算法的时间复杂度和空间复杂度了,那我来讲讲怎么计算。        常用的算法的时间复杂度和空间复杂度 一,求解算法的时间复杂度,其具体步骤是: ⑴ 找出算法...博文来自:杨威的博客

  近年来深度学习捷报连连,声名鹊起,随机梯度下架成了训练深度网络的主流方法。尽管随机梯度下降法,将对于训练深度网络,简单高效,但是它有个毛病,就是需要我们人为的去选择参数,比如学习率、参数初始化等,这些...博文来自:hjimce的专栏

  运行时数据区域Java虚拟机在执行Java程序的过程中会把它所管理的内存区域划分为若干个不同的数据区域。这些区域都有各自的用途,以及创建和销毁的时间,有的区域随着虚拟机进程的启动而存在,有些区域则...博文来自:小小本科生成长之路

  原文地址:因为需要用,所以才翻译了这个文档。但总归赖于英语水平很有限,翻译出来的中文有可能...博文来自:ymj7150697的专栏

  1. 前言 海外游戏运营,facebook渠道和账号体系,覆盖范围是比较全面的,即使是在非英语母语地区如台湾和东南亚都有大量用户。所以接入,fb sdk的需求就这样出来了。 2. faceboo...博文来自:kahuka

  采用EasyUI 1.4.x 版本,默认default风格,异步加载页面,多Tab页展示,使用JSON文件模拟从后台动态获取数据。...博文来自:般若

  单机最大的TCP连接数及其修改 一个误解: 单个服务器程序可承受最大连接数“理论”上是“65535” .    65535这个数字的由来,很多人想当然地将它与port最大值联系起来。的确,TCP的...博文来自:田发江的专栏

  写在前面这一篇是在Digital Tutors的一个系列教程的基础上总结扩展而得的~Digital Tutors是一个非常棒的教程网站,包含了多媒体领域很多方面的资料,非常酷!除此之外,还参考了Uni...博文来自:candycat

  最近比较有空,大四出来实习几个月了,作为实习狗的我,被叫去研究Docker了,汗汗! Docker的三大核心概念:镜像、容器、仓库 镜像:类似虚拟机的镜像、用俗话说就是安装文件。 容器:类似一个轻量...博文来自:我走小路的博客

  强连通分量: 简言之 就是找环(每条边只走一次,两两可达) 孤立的一个点也是一个连通分量   使用tarjan算法 在嵌套的多个环中优先得到最大环( 最小环就是每个孤立点)   定义: int Ti...博文来自:九野的博客

  Cocos2d-x 2.2.3 使用NDK配置编译环境2014年6月11日 Cocos2d-x 3.0以下的开发环境的配置恐怕折磨了很多人,使用cygwin配置编译环境足够让初学者蛋疼一阵子了。本篇博...博文来自:巫山老妖

  jquery/js实现一个网页同时调用多个倒计时(最新的) 最近需要网页添加多个倒计时. 查阅网络,基本上都是千遍一律的不好用. 自己按需写了个.希望对大家有用. 有用请赞一个哦! //js ...博文来自:Websites

  网络积件方案(实现篇)       上篇我已经阐述了使用HTML之类的文本格式的好处,下面我想就积件的表现方式描述一下。        积件不同于网页,因为积件其实是小型的课件,它与网页的最大不同之处...博文来自:李逍遥的DELPHI专栏

  mina自带了心跳包机制,我是每隔15秒发送一次心跳包,若30秒内没有收到,则认为超时。 网络连接的主题函数是: /** * 30秒后超时 */ private st...

  一、代理模式为某个对象提供一个代理,从而控制这个代理的访问。代理类和委托类具有共同的父类或父接口,这样在任何使用委托类对象的地方都可以使用代理类对象替代。代理类负责请求的预处理、过滤、将请求分配给委托...

  颜家大少的博客魔兽争霸3冰封王座1.24e 多开联机补丁 信息发布与收集点

  上一篇文章讲解了SNMP的基本架构,本篇文章将重点分析SNMP报文,并对不同版本(SNMPv1、v2c、v3)进行区别! 四、SNMP协议数据单元 在SNMP管理中,管理站(NMS)和代理(Age...

  自己整理编写的逻辑回归模板,作为学习笔记记录分享。数据集用的是14个自变量Xi,一个因变量Y的australian数据集。 1. 测试集和训练集3、7分组 australian ...

  本文介绍如何使用VS2015作为编译开发环境,调用OpenCV3.31和Qt5.9.1写图像处理的GUI。 1.目录结构 假设我们要创建一个名为VideoZoom的工程,那么首先按下图构建目录结构...