函数参数的扩展
1.默认参数
function fn(a, b = 10) {
console.log(a, b)
}
fn(10) //10 10
只有在未传递参数,或者参数为 undefined 时,才会使用默认参数,null 值被认为是有效的值传递。
function fn(a, b = 10, c = 10) {
console.log(a, b, c)
}
fn(10, undefined, null) //10 10 null
函数参数默认值存在暂时性死区,在函数参数默认值表达式中,还未初始化赋值的参数值无法作为其他参数的默认值。
function f(x,y=x){
console.log(x,y);
}
f(1); // 1 1
function f(x=y){
console.log(x);
}
f(); // ReferenceError: y is not defined
2. 不定参数用来表示不确定参数个数,形如,…变量名,由…加上一个具名参数标识符组成。具名参数只能放在参数组的最后,并且有且只有一个不定参数。
function f(...values){
console.log(values.length); //values为一个纯数组
}
f(1,2); //2
f(1,2,3,4); //4
函数的length属性失真
在给函数指定默认参数后,函数的length将会失真。也就是说,函数的length只会是没有默认值的参数的个数。
function test(a, b, c=1) {}
console.log(test.length) //2
并且,如果默认值参数没有在末尾,那么函数的length属性为默认参数之前的参数个数
function test(a=1, b, c) {}
console.log(test.length) //0
function test(a, b=1, c) {}
console.log(test.length) //1
函数的length属性,不包括 rest 参数。
(function(a) {}).length // 1
(function(...a) {}).length // 0
(function(a, ...b) {}).length // 1
函数的name属性
函数的name属性,返回该函数的函数名。
function foo() {}
foo.name // "foo"
如果将一个匿名函数赋值给一个变量,ES5 的name属性,会返回空字符串,而 ES6 的name属性会返回实际的函数名。
如果将一个具名函数赋值给一个变量,则 ES5 和 ES6 的name属性都返回这个具名函数原本的名字。
function demo(){}
demo.name // 'demo'
let demo = function(){}
demo.name // ''
let demo = function test(){}
demo.name // 'test'
箭头函数
var f = a => a
// 等价于
var f = function (a) {
return a
}
当箭头函数没有参数或者有多个参数,要用 () 括起来。
//没有参数
var f = () => {
console.log('我是箭头函数')
}
// 等价于
var f = function () {
console.log('我是箭头函数')
}
//两个及两个以上的参数
var f = (a, b) => {
console.log('我是箭头函数')
}
// 等价于
var f = function (a, b) {
console.log('我是箭头函数')
}
当箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。
var f = a => a
// 等价于
var f = function (a) {
return a
}
当箭头函数要返回对象的时候,为了区分于代码块,要用 () 将对象包裹起来
// 报错
var f = (id,name) => {id: id, name: name};
f(6,2); // SyntaxError: Unexpected token :
// 不报错
var f = (id,name) => ({id: id, name: name});
f(6,2); // {id: 6, name: 2}
使用注意点
箭头函数有几个使用注意点。
(1)箭头函数没有自己的this对象(详见下文)。
(2)不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出一个错误。
(3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。
(4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
上面四点中,最重要的是第一点。对于普通函数来说,内部的this指向函数运行时所在的对象,但是这一点对箭头函数不成立。它没有自己的this对象,内部的this就是定义时上层作用域中的this。也就是说,箭头函数内部的this指向是固定的,相比之下,普通函数的this指向是可变的。