函数的扩展(es6)

274 阅读4分钟

ES6总结系列之 函数的扩展 篇


函数参数默认值

参数变量是默认声明的,所以不能用let或const再次声明

function foo(x = 5) {
  let x = 1; // error
  const x = 2; // error
  var x = 3; //不报错
}

使用参数默认值时,函数不能有同名参数

// 不报错
function foo(x, x, y) {
  // ...
}

// 报错
function foo(x, x, y = 1) {
  // ...
}

参数默认值是惰性求值的,每次都重新计算默认值

let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101
//每次调用函数foo时都会重新计算参数x+1

函数length属性失真,不包括默认值参数,rest参数

length属性在有指定默认值的函数中,只返回没有默认值的参数的个数。即在有默认值参数的函数中,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

rest参数同理:

(function(...args) {}).length // 0

作用域

设置了参数默认值,函数进行声明初始化时,参数会形成一个单独作用域,等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。

var x = 1;

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

f(2) // 2

下面是更复杂的例子

var x = 1;
function foo(x, y = function() { x = 2; }) {
  var x = 3;
  y();//y函数中的x指向参数x
  console.log(x);
}

foo() // 3
x // 1
var x = 1;
function foo(x, y = function() { x = 2; }) {
  x = 3;//x与参数x是一致的
  y();//y函数中的x指向参数x
  console.log(x);
}

foo() // 2
x // 1

rest参数

rest参数形式为(...变量名)

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

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

  return sum;
}

add(2, 5, 3) // 10

rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错

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

函数的length属性,不包括 rest 参数。

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

箭头函数

①箭头函数里的this就是定义所在的对象,不是使用时所在的对象,箭头函数没有自己的this,导致内部的this就是外层代码块中的this

②由于箭头函数没有自己的this,所以当然也不能用call(), apply(), bind()改变this指向

③不可以用作构造函数,即不可以使用new命令(没有this)

④不存在arguments对象,可用rest参数代替

⑤对象不构成单独的作用域

导致jumps箭头函数定义时的作用域就是全局作用域。

const cat = { 
    lives: 9, 
    jumps: () => { this.lives--; }//指向全局作用域
}
ES6新增了大括号{}表示的块级作用域,但是对象并不构成单独的作用域

总结要点

函数参数默认值

  • 参数变量是默认声明的,所以不能用let或const再次声明
  • 使用参数默认值时,函数不能有同名参数
  • 函数length属性失真,不包括默认值参数,rest参数
  • 参数默认值是惰性求值的,每次都重新计算默认值
  • 作用域:设置了参数默认值,函数进行声明初始化时,参数会形成一个单独作用域

rest参数

  • rest参数形式为(...变量名)
  • rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错
  • 函数的length属性,不包括 rest 参数。

箭头函数

  • 箭头函数里的this就是定义所在的对象,不是使用时所在的对象,箭头函数没有自己的this,导致内部的this就是外层代码块中的this
  • 由于箭头函数没有自己的this,所以当然也不能用call(), apply(), bind()改变this指向
  • 不可以用作构造函数,即不可以使用new命令(没有this)
  • 不存在arguments对象,可用rest参数代替
  • 对象不构成单独的作用域

  • 个人Github,欢迎star^_^
  • ES6总结系列参考自阮一峰《ECMAScript6入门》