参数的默认值
-
=== undefined
触发 - 可搭配解构使用
- 位置:有默认值的参数通常作为尾参数
- length: 有默认值的不算在 func.length 中,如果不是尾参数,其后面的也都不算在内
- 作用域: 一旦设置了参数默认值,在函数进行声明初始化时,参数会形成一个单独的作用域,初始化结束则此作用域消失。
rest 参数
-
function add(...values)
function push(array, ...items)
- 只能是最后一个参数
- 替代
arguments
变量,arguments
是类数组,而 rest 参数是真正的数组 - 也不算进函数的 length 属性里
严格模式
- ES5 规定函数里可以设定 'use strict'
- ES6 规定,如果函数参数使用了默认值、解构赋值、扩展符则不能在内部显式地设定严格模式。因为函数内的严格模式对函数参数和函数体内都生效,而在函数里设定的话,进入函数体才会发现严格模式,但此时参数的运算已经完成。
新加 name 属性
(function foo(){}).name // "foo"
(() => {}).name // ""
const bar = () => {}; bar.name // "bar"
(new Function).name // "anonymous"
(function foo(){}).bind({}).name // "bound foo"
(() => {}).bind({}).name // "bound "
箭头函数
- 直接返回一个对象的话用括号括起来
const obj = (param) => ({p: param})
- 没有
this
arguments
变量,也没有super
new.target
变量 - 不能用于
new
命令,即不能用作构造函数 - 不能用于
yield
命令,即不能用作 Genorator 函数 - 箭头函数“绑定”了 this,指的是箭头函数中的 this 始终指向函数定义时所处的对象,这是由于箭头函数本身没有 this 变量,于是它内部 this 变量就会沿作用域链向上查找,这个作用域链就是函数定义时的作用域链;而普通函数中本身存在 this 变量,指向调用函数的对象,是动态的。
- 因此,不要用于定义对象的方法,也不要用于需要动态 this 的地方
尾调用优化
- 尾调用,指在函数中最后执行的一步是调用一个函数(并 return,否则 return false 才算最后一步)
- 优化是指将调用栈中尾调用所在函数的调用帧释放掉(已执行到最后一步,函数的变量和执行位置无需再记录了)
- 优化的真正价值在于尾递归,即尾调用自身,这样将递归的复杂度由O(n)降到了O(1),避免了栈溢出或超时的问题
- 并非所有浏览器都已实现
- 只在严格模式中生效,因为在非严格模式中存在 func.arguments 和 func.caller 会跟踪函数的调用栈,优化会使其失真,而严格模式中不存在这两个变量
- 因此将递归改写成尾递归形式可实现优化
- 在不支持的环境中,可以模拟优化,例如蹦床函数(trampoline)可以将递归执行转为循环执行
函数参数的尾逗号
- 为了增删参数时版本管理系统无冗余
- 和数组、对象的尾逗号规则保持了一致
toString
-
Function.prototype.toString
方法原样打印函数代码,不再删掉注释和空格
catch
-
try {} catch (err) {}
中catch
不再必须有参数,可写成try {} catch {}