函数的默认值
- 默认值生效的条件是严格等于(===)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 的尾调用优化只在严格模式下开启,正常模式是无效的。