ES6学习—函数的扩展

1.函数参数的默认值

(1)基本用法

ES6之前不能直接给函数的参数指定默认值,只能通过变通的方法

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

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

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

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

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

ES6写法的优点:
(1).简洁,提升阅读效率
(2).阅读代码的人可以在不用查看函数体或文档,就立刻意识到哪些参数是可以被省略的。
(3).代码优化,即使未来的版本在对外接口中,彻底拿掉这个参数,也不会导致以前的代码无法运行

参数变量是默认声明的,所以不能用let或const再次声明,否则会报错。

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

使用参数默认值需要注意的:
(1).函数不能有同名参数
(2).参数默认值不能够传值,每次都重新计算默认值表达式的值。也就是参数默认值是惰性求值的。

// 同名函数报错
function foo(x, x, y = 1) {
  // ...
}
// SyntaxError: Duplicate parameter name not allowed in this context
******************************
let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101

上面代码中,参数p的默认值是x + 1。这时,每次调用函数foo,都会重新计算x + 1,而不是默认p等于 100。

(2)与解构赋值默认值结合使用

参数默认值可以与解构赋值的默认值,结合起来使用。

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

foo({}) // undefined 5
foo({x: 1}) // 1 5
foo({x: 1, y: 2}) // 1 2
foo() // TypeError: Cannot read property 'x' of undefined

上面代码只使用了对象的解构赋值默认值,没有使用函数参数的默认值。只有当函数foo的参数是一个对象时,变量x和y才会通过解构赋值生成。如果函数foo调用时没提供参数,变量xy就不会生成,从而报错。通过提供函数参数的默认值,就可以避免这种情况.

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

foo() // undefined 5

上面代码指定,如果没有提供参数,函数foo的参数默认为一个空对象。

(3).参数默认值的位置
通常情况下,函数默认值应该是函数的尾参数,这样比较容易看出到底省略了哪些参数。如果非尾参数设置默认值,这个参数无法被忽略,否则会报错,除非显式输入`undefined`,传入`undefined`将会触发该参数的默认值,`null`没有这个效果
/ 例一
function f(x = 1, y) {
  return [x, y];
}

f() // [1, undefined]
f(2) // [2, undefined])
f(, 1) // 报错
f(undefined, 1) // [1, 1]

// 例二
function f(x, y = 5, z) {
  return [x, y, z];
}

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 报错
f(1, undefined, 2) // [1, 5, 2]
function foo(x = 5, y = 6) {
  console.log(x, y);
}

foo(undefined, null)

上面代码中,x参数对应undefined,结果触发了默认值,y参数等于null,就没有触发默认值。

(4)函数的 length 属性

指定了默认值后,函数length将返回不包含默认值的参数个数,同样的rest参数也不会计入length属性,指定了默认值后,length属性将失真。

(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2

如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数了。

(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1

(6).作用域
一旦设置了函数默认值,函数在声明初始化时,函数就会形成一个单独的作用域,初始化结束后这个作用域会消失。不设置函数默认值就不会出现作用域。

var x = 1;

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

f(2) // 2

上面代码中,参数y的默认值等于变量x。调用函数f时,参数形成一个单独的作用域。在这个作用域里面,默认值变量x指向第一个参数x,而不是全局变量x,所以输出是2
如果此时,全局变量x不存在,就会报错。

function f(y = x) {
  let x = 2;
  console.log(y);
}

f() // ReferenceError: x is not defined

2.rest参数

ES6引入rest参数(形式为“...变量名”),用于获取函数的多余参数。
函数参数搭配的变量是一个数组,该变量将多余的参数翻到里面。

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

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

  return sum;
}

add(2, 5, 3) // 10

上面代码的add函数是一个求和函数,利用 rest 参数,可以向该函数传入任意数目的参数。

下面是一个 rest 参数代替arguments变量的例子。

// arguments变量的写法
function sortNumbers() {
  return Array.prototype.slice.call(arguments).sort();
}

// rest参数的写法
const sortNumbers = (...numbers) => numbers.sort();

上面代码的两种写法,比较后可以发现,rest参数的写法更自然也更简洁

注意:
(1). rest参数之后不能有其他参数,即只能是最后一个参数,否则会报错
(2).函数的length属性不包括rest参数
// 报错

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

(function(a) {}).length  // 1
(function(...a) {}).length  // 0
(function(a, ...b) {}).length  // 1

3.箭头函数

基本用法
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;
};
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 函数参数的默认值 基本用法 在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 上面代码检查函数l...
    呼呼哥阅读 3,691评论 0 1
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,442评论 0 13
  • 虽是平静似海 湛蓝的一望无际 但却心潮澎湃 抽动着自己的灵魂 我站在一块毅然不动的巨石上 任风拍打自己的身躯 一阵...
    季晓蒿阅读 334评论 4 11
  • 作者:李希烈(Chris Lee) 美敦力全球高级副总裁兼亚太区总裁 - 27岁出任跨国公司总经理,成为这家全球制...
    百胜2117阅读 1,436评论 0 0

友情链接更多精彩内容