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入门》