函数的扩展

ES6 对函数做了很多扩展.

函数参数的默认值

ES6 允许为函数的参数设置默认值:

function point (x = 0, y = 0){
  this.x = x;
  this y = y;
}
var p = new point();
p{x: // 0 , y:  //0}

但是在一般的情况下,定义了默认值的参数应该是函数的尾参数,如果非尾部的参数设置了默认值,实际上这个参数是无法省略的.

function f(x= 1,y){
  return [x,y];
}
f();  //[1,undefined]
f(2);  //[2,undefined]
f( ,1)  //报错
f(undefined, 1) //[1,1]

函数参数默认值的作用域

一旦设置了参数的默认值,参数会形成一个单独的作用域,等到初始化完成之后,这个作用域才会消失.

var x = 1
function f(x, y = x) {
  console.log(y)
}
f(2) //2

在这个例子中,y 的默认值设置为等于 x,形成了单独的作用域,于是 y 的值就和全局的 x 无关,调用 f(2)的时候就将 x 的值赋给 y.如图

另一个例子

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

那么在这个例子中,调用f()时,x 初始化为let x = 1,所以形成单独的作用域,y=x=1,与里面的let x = 2 无关.如图

rest 参数

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

function add(...values) {
  let sum = 0
  for (var val of values) {
    sum += val
  }
}
add(2, 5, 3) //10

ES6 规定只要函数的参数使用了默认值、解构赋值或者扩展运算符,那么函数的内部不允许设定为严格模式.

函数的 name 属性

name 属性会返回该函数的函数名.

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

匿名函数的 name 属性在 ES5 和 ES6 的区别如下:

var f = function () {
  ...
}
f.name  // " "  ES5
f.name  // "f"  ES6

箭头函数

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
}

如果箭头函数的代码块部分多于一条语句,就应该使用大括号将其括起来.

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

由于打括号被解释为一个代码块,所以如果箭头函数返回的是一个对象,就必须在对象外面加上括号.

var getTempItem = (id) => ({
  id: id,
  name: "temp"
})

rest 参数和箭头函数的结合.

const numbers = (...nums) => nums
numbers(1, 2, 3, 4, 6) //[1,2,3,4,6]
const headAndTail = (head, ...tail) => [head, tail]
headAndTail(1, 2, 3, 4, 5) //[1,[2,3,4,5]]

箭头函数的注意事项

函数体内的this对象就是定义时所在的对象,而不是使用时所在的对象.this对象的指向是可变的,但在箭头函数中它是固定的.