Skip to content

函数的默认值

  • 默认值生效的条件是严格等于(===)undefined
  • 参数变量是默认声明的,所以不能再次声明
function foo (x = 5) {
    let x  = 1 // error
    const x = 2 // error
}
  • 使用参数默认值时函数不能有同名参数
function foo (x, x, y) {}   // 不报错
function foo (x, x, y = 0) {}   // 报错
  • 参数默认值是惰性求值的,只有在用到的时候才会求值
  • 参数默认值的位置应该是尾参数
  • 设置参数默认值之后函数的 length 属性将返回默认值之前的参数个数,也就是说设置默认参数后 length 将失真
(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
(function(...args) {}).length // 0
  • 设置参数的默认值,在函数进行声明初始化时参数会形成一个单独的作用域,等初始化结束作用域会消失。不设置默认值是不会出现的。
var x = 1
function f(x, y = x) {
    console.log(y)
}
f(2)

rest 参数

rest 参数(形式为 ...变量名 ),用于获取函数的多余参数

  • rest 参数之后不能再有其他参数
  • 函数的 length 属性不包含 rest 参数

严格模式

只要函数的参数使用了默认值,解构赋值,或者扩展运算符那么函数内部就不能设为严格模式

name 属性

返回函数的函数名

  • 匿名函数赋值给变量,name 为变量名
  • 具名函数赋值给变量,name 为具名函数原来的名字
  • Function 构造函数返回函数实例,name 为 anonymous
  • bind 返回的函数,name 属性会加上 bound 前缀
(new Function).name // "anonymous"
function foo() {};
foo.bind({}).name // "bound foo"
(function(){}).bind({}).name // "bound "

箭头函数

  • 如果箭头函数只有一行语句且不用返回值,语句前加 void
() => void doesNotReturn();
  • 函数体内的 this 对象,就是定义时所在的对象,而不是使用时所在的对象
  • 不可当作构造函数(不可以使用 new 命令)
  • 不可以使用 arguments 对象
  • 不可使用 yield 命令,箭头函数不能用作 Generator 函数

嵌套的箭头函数

前一个函数的输入是后一个函数的输入

绑定 this

箭头函数可以绑定 this 对象,大大减少了显示绑定 this 对象的写法(call, apply, bind)。 函数绑定运算符是并排的两个冒号,左边是一个对象,右边是一个函数。该运算符会将左边的对象作为上下文环境(this)绑定到右边的函数上。

foo::bar
// 等同于
bar.bind(foo)

如果双冒号左边为空右边是一个对象的方法,则等于将该方法绑定在该对象上

::console.log
// 等同于
console::console.log
console.log.bind(console)

尾调用优化

在函数的最后一步调用另一个函数。尾调用是最后一步操作。尾调用调用帧只有一项,可以节省内存。

尾递归

递归调用非常消耗内存很容易发生栈溢出错误,但是尾递归永远只存在一个调用帧

  • 递归函数的改写:需要将中间变量改写为函数的参数。

严格模式

ES6 的尾调用优化只在严格模式下开启,正常模式是无效的。