JavaScript函数的多种写法

如果你曾与JavaScript代码打过交道,你应该会很熟悉如何定义和调用函数,但是你真的知道有多少种定义函数的方法吗?对于编写和维护测试Test262(浏览器JavaScript标准测试)来说,这是一个十分常见的挑战,尤其是当一个新特性出现且与现有的函数语法有关联,或者扩展了现有函数的API时。有必要确保新的或被提议的语法和API是有效的,且对语言中的每一个现有变体都是有效的。

本文内容是对JavaScript中已经存在的函数语法格式的概述说明。本文档不包括类声明和表达式,因为这些形式生成的对象不是“可调用的”,对于本文来说,我们只关注生成“可调用的”函数对象的格式。此外,这篇文章也不包括参数列表(包括默认参数、解构,或者尾逗号),因为这些话题足够再写一篇文章了。


大家都知道,最广泛应用也是最早的函数定义形式就是函数声明和函数表达式。前者是最初设计的一部分(1995)并出现在第一个版本的规范(1997年)中,后者是在第三个版本(1999年)引入的。我们可以从这些规范中提取三种不同的定义形式

Function构造器

当我们在讨论一种语言的“函数API”的时候,就已经开始讨论Function构造器。在考虑最初的语言设计时,函数声明的语法形式可以被解释为函数构造器的API的“文字”形式。Function构造器为定义函数提供了一种方法:通过N个字符串参数指定函数参数和函数主体,(如下面的例子)最后一个字符串参数始终是函数主体(需要指出的是,这是一种动态求值形式,会有潜在的安全风险)。对于大多数情况来说,这种形式并不适合,因此它的使用非常稀少——但是自从第一个版本的ECMAScript以来,它就一直存在在JavaScript 中了。

自从ES2015推出以来,已经引入了几种新的语法形式。这些形式的变化是巨大的!

not-so-anonymous函数声明

这是一种新的匿名函数声明形式,如果你曾用过ES Modules,应该清楚这种语法。虽然它可能看起来与匿名函数表达式非常相似,但它实际上有一个默认名称,即“default”

方法定义

对于下面这个例子,大家应该能很快发现它定义了匿名和命名函数表达式作为属性的值。注意,这些不是不同的语法形式。它们是之前讨论过的函数表达式的示例,是在初始对象时编写的。这种形式最初是在ES3中引入的。

箭头函数

作为ES2015最具争议性的函数之一,箭头函数已经变得众所周知且无处不在。箭头函数语法是这样定义的,它为函数声明提供了两种不同的格式:赋值表达式(箭头后面没有跟“{”大括号时为赋值表达式)和函数体(代码中包括0到多个语句时为函数体)。这个语法还允许在描述单个参数时不加圆括号,然而0个或一个以上参数需要加圆括号。这些语法结构允许箭头函数拥有多种书写形式:

未被括起来的形式——也就是没有圆括号的形式——即在箭头函数只能表现为只用一个标识符名称作为参数的形式。当箭头函数在异步函数或生成器中定义时,这个标识符名称需要以await或yeild作为前缀定义。但这是我们在箭头函数中能得到的最大程度的不用括号括起来参数列表的情况。

箭头函数可以(也经常)出现在初始化值或属性定义的赋值中,上面所示的箭头函数表达式已经包括了这种情况

生成器

生成器有一种特殊的语法,除了箭头函数和定义setter / getter方法的时候不能添加之外,可以被添加在其他所有语法形式中。我们可以用其生成函数声明、表达式、定义,甚至构造函数。

ES2017

异步函数

经历了几年的发展,异步函数将于2017年6月发布ES2017的EcmaScript语言规范的第8版引入。尽管如此,许多开发人员已经使用了这个特性,这要归功于Babel的早期实现支持!

Async函数语法为描述异步操作提供了一种干净而统一的方式。调用时,Async函数对象将返回一个Promise对象,这个对象将在异步函数返回时被解析。当包含一个await表达式时,异步函数可能暂停函数的执行,然后将其用作异步函数的返回值

继续更新的ES2017

异步生成器 Async Generators

在接下来的ES017中,async和await关键字将被扩展以支持新的异步生成器形式。这个特性的进展可以通过proposal’s github repository进行跟踪。您可能已经猜到,这是async、await和现有的生成器声明和生成器表达式语法的组合。调用时,异步生成器返回一个迭代器,它的next()方法返回Promise对象然后用迭代器对象解析,而不是直接返回迭代器对象。

可以在许多地方发现异步生成器,你可能已经生成器函数中见到它了。

复杂的挑战

每个函数语法格式不仅对学习和使用是挑战,而且对JS运行时间和Test262的实现和维护也是一个挑战。当引入新的语法形式时,Test262必须与所有相关的语法规则一起测试该新形式。例如,将默认参数语法的测试形式限制在简单的函数声明形式中,并假设在其他格式下该语法也正常起作用是不明智的。每一个语法规则都必须经过测试,将这些测试任务分配给一个人是不合理的。所以导致了测试生成工具的设计和实现。测试生成工具提供了一种确保能够覆盖(函数格式的多少)更详尽的方法。

这个项目现在包含了一系列由不同的测试用例和模板组成的源文件,例如,如何检查每个函数格式的参数,或者函数格式测试,甚至更多超出范围的函数形式,在这些函数形式中,解构绑定和解构赋值都是适用的。

尽管它可能导致密集的和长时间的发送请求,但是覆盖率总是会提高,而且可能总是会发现新的错误。

为什么了解所有的函数格式是很重要的?

如果不需要在Test262上编写测试,计算和列出所有函数表单可能并不重要。这里已经列出了许多格式的模板。新的测试可以很容易地使用现有的模板作为起点。

确保EcmaScript规范的良好测试是Test262的主要任务。这对所有的JavaScript运行时间都有直接的影响,我们识别的格式越多,覆盖率就越全面,这将帮助新功能更无缝地集成,不管您使用的平台是什么。

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

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,637评论 18 139
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,171评论 9 118
  • 你不知道JS:异步 第四章:生成器(Generators) 在第二章,我们明确了采用回调表示异步流的两个关键缺点:...
    purple_force阅读 950评论 0 2
  • 函数函数定义与调用变量作用域全局变量方法高阶函数闭包箭头函数$generator$ 函数 函数定义与调用 定义函数...
    染微言阅读 578评论 0 5
  • 函数和对象 1、函数 1.1 函数概述 函数对于任何一门语言来说都是核心的概念。通过函数可以封装任意多条语句,而且...
    道无虚阅读 4,550评论 0 5