ES6 函数的扩展

ES6 函数的扩展

大家好,又见面了,我是你们的朋友全栈君。

函数参数的默认值

ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法。

function log(x, y) {
  // y = y || 'World';
  if (typeof y === 'undefined') {
      y = 'World';
  }
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello World

ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。

function log(x, y = 'World') {
  console.log(x, y);
}

log('Hello') // Hello World
log('Hello', 'China') // Hello China
log('Hello', '') // Hello

参数变量是默认声明的,所以不能用letconst再次声明。

function foo(x = 5) {
  let x = 1; // error
  const x = 2; // error
}

与解构赋值默认值结合使用

function foo({x, y = 5} = {}) {
  console.log(x, y);
}

foo() // undefined 5
function fetch(url, { body = '', method = 'GET', headers = {} } = {}) {
  console.log(method);
}

fetch('http://example.com')
// "GET"

rest参数

ES6 引入 rest 参数(形式为…变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

function add(...values) {
  let sum = 0;

  for (var val of values) {
    sum += val;
  }

  return sum;
}

add(2, 5, 3) // 10

注意,rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。

// 报错
function f(a, ...b, c) {
  // ...
}

严格模式

ES2016 做了一点修改,规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错。

// 报错
function doSomething(a, b = a) {
  'use strict';
  // code
}

// 报错
const doSomething = function ({a, b}) {
  'use strict';
  // code
};

// 报错
const doSomething = (...a) => {
  'use strict';
  // code
};

const obj = {
  // 报错
  doSomething({a, b}) {
    'use strict';
    // code
  }
};

name 属性

函数的name属性,返回该函数的函数名。

function foo() {}
foo.name // "foo"

这个属性早就被浏览器广泛支持,但是直到 ES6,才将其写入了标准。

需要注意的是,ES6 对这个属性的行为做出了一些修改。如果将一个匿名函数赋值给一个变量,ES5 的name属性,会返回空字符串,而 ES6 的name属性会返回实际的函数名。

var f = function () {};

// ES5
f.name // ""

// ES6
f.name // "f"

如果将一个具名函数赋值给一个变量,则 ES5 和 ES6 的name属性都返回这个具名函数原本的名字。

const bar = function baz() {};

// ES5
bar.name // "baz"

// ES6
bar.name // "baz"

箭头函数

ES6 允许使用“箭头”(=>)定义函数。

var f = v => v;

// 等同于
var f = function (v) {
  return v;
};

如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。

var f = () => 5;
// 等同于
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};

如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。

var sum = (num1, num2) => { return num1 + num2; }

由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

// 报错
let getTempItem = id => { id: id, name: "Temp" };

// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });

箭头函数可以与变量解构结合使用。

const full = ({ first, last }) => first + ' ' + last;

// 等同于
function full(person) {
  return person.first + ' ' + person.last;
}

箭头函数的一个用处是简化回调函数。

// 正常函数写法
[1,2,3].map(function (x) {
  return x * x;
});

// 箭头函数写法
[1,2,3].map(x => x * x);

下面是 rest 参数与箭头函数结合的例子。

const numbers = (...nums) => nums;

numbers(1, 2, 3, 4, 5)
// [1,2,3,4,5]

const headAndTail = (head, ...tail) => [head, tail];

headAndTail(1, 2, 3, 4, 5)
// [1,[2,3,4,5]]

嵌套的箭头函数

箭头函数内部,还可以再使用箭头函数。下面是一个 ES5 语法的多重嵌套函数。

function insert(value) {
  return {into: function (array) {
    return {after: function (afterValue) {
      array.splice(array.indexOf(afterValue) + 1, 0, value);
      return array;
    }};
  }};
}

insert(2).into([1, 3]).after(1); //[1, 2, 3]

上面这个函数,可以使用箭头函数改写。

let insert = (value) => ({into: (array) => ({after: (afterValue) => {
  array.splice(array.indexOf(afterValue) + 1, 0, value);
  return array;
}})});

insert(2).into([1, 3]).after(1); //[1, 2, 3]

函数参数的尾逗号

此前,函数定义和调用时,都不允许最后一个参数后面出现逗号。

function clownsEverywhere(
  param1,
  param2
) { /* ... */ }

clownsEverywhere(
  'foo',
  'bar'
);

如果像上面这样,将参数写成多行(即每个参数占据一行),以后修改代码的时候,想为函数clownsEverywhere添加第三个参数,或者调整参数的次序,就势必要在原来最后一个参数后面添加一个逗号。这对于版本管理系统来说,就会显示添加逗号的那一行也发生了变动。这看上去有点冗余,因此新的语法允许定义和调用时,尾部直接有一个逗号。

function clownsEverywhere(
  param1,
  param2,
) { /* ... */ }

clownsEverywhere(
  'foo',
  'bar',
);

这样的规定也使得,函数参数与数组和对象的尾逗号规则,保持一致了。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/107446.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • C 单向链表排序_单向链表排序java

    C 单向链表排序_单向链表排序java链表排序链表排序的两种方式一、交换结点的数据域二、断开链表,重新形成方法示例链表排序的两种方式一、交换结点的数据域有很多种方法,比如冒泡排序,选择排序等其他排序方法structNode*link_sort(structNode*head){ intvalue; structNode*p=head; structNode*q=NULL; while(p) { q=p->next; while(q) { if(p->data&g

    2022年10月11日
    0
  • hadoop使用教程_hadoop入门

    hadoop使用教程_hadoop入门Hadoop【大数据Hadoop系列】Hadoop2.X单机环境搭建【大数据Hadoop系列】Hadoop2.X集群环境搭建MapReduce【大数据Hadoop系列】分布式计算框架——MapReduceYARN【大数据Hadoop系列】Hadoop-YARN知识体系总结(2021版)【大数据Hadoop系列】集群资源管理器——YARNHDFS【大数据Hadoop系列】Hadoop-HDFS知识体系总结(2021版)【大数据Hadoop系列】Hadoop分

    2025年6月3日
    0
  • MySQL数据库免安装版配置教程及常见问题[通俗易懂]

    MySQL数据库免安装版配置教程及常见问题[通俗易懂]MySQL是一款安全、跨平台、高效的,并与PHP、Java等主流编程语言紧密结合的数据库系统。以下教程以windows1064位计算机为例(其他windows系统类似)01下载官方网站下载https://dev.mysql.com/downloads/mysql/根据自己的电脑配置选择对应版本.zip压缩包格式下载。无需登录,直接下载百度云快捷下载链接:https://pan.baidu.com/s/1hcEKFAQ6Fq7kFLG8x7SQCQ提取码:2bfg02配

    2022年7月20日
    15
  • users的权限_user是啥

    users的权限_user是啥MySQL在安装时会自动创建一个名为mysql的数据库,mysql数据库中存储的都是用户权限表。用户登录以后,MySQL会根据这些权限表的内容为每个用户赋予相应的权限。user表是MySQL中最重要的一个权限表,用来记录允许连接到服务器的账号信息。需要注意的是,在user表里启用的所有权限都是全局级的,适用于所有数据库。user表中的字段大致可以分为4类,分别是用户列、权限列、安全列、资源控制列,下面主要介绍这些字段的含义。用户列用户列存储了用户连接MySQL

    2022年9月29日
    0
  • 数论——欧拉函数

    数论——欧拉函数定义小于n的正整数中与n互质的数的数目(φ(1)=1)通式证明:设p是N的质因子,1~N中p的倍数有p,2p,3p,…,(N/p)*p,共N/p个。同理,若q也是N的质因子,则1~N中q的倍

    2022年7月2日
    24
  • treetable怎么带参数_好用的TreeTable插件

    treetable怎么带参数_好用的TreeTable插件插件描述:实现layui的树形表格treeTable,对layui数据表格进行扩展。注:加载了外部json数据文件,本地预览会有跨域问题,需要在服务端运行。treetable-lay实现layui的树形表格treeTable1.简介在layui数据表格之上进行扩展实现。2.使用方法2.1.引入模块下载module/treetable-lay整个文件夹,放在你的项目里面,然后使用模块加载的方式使用:…

    2022年5月29日
    38

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号