1.函数参数的默认值
函数的参数允许带有默认值,参数变量是默认声明的,无需使用let或const再次声明。
function f ( x = 1 , y = 2 ) { ... }
function f ( x, x, y ) { ... }
function f ( x, x, y = 1 ) { ... }
(1)函数默认值与解构赋值结合使用
function f ( { x, y = 5 } ) { ... }
f ( { X : 1 } )
f ( { } )
f ( )
function ( { x, y = 5 } = { } )
f ( )
(2)默认参数的位置
function f ( x = 1 , y ) { ... }
f ( )
f ( 2 )
f ( , 2 )
function f ( x, y = 1 ) { ... }
f ( 1 )
(3)函数的length属性
函数的length属性可以返回参数的个数,但是参数指定了默认值之后,length会失真
,只返回指定默认值参数之前的个数。rest参数也是同理。
( function f ( x, y, z ) { ... } ) . length
( function f ( x, y = 1 , z ) { ... } ) . length
( function f ( x = 1 , y = 2 , z = 3 ) { ... } ) . length
( function ( ... args) { } ) . length
(4)严格模式问题
只要函数参数使用了默认值、解构赋值、rest
等就不能在函数内部显式的设定为严格模式,否则会报错。 解决办法一个是在全局设定严格模式;另一个是在函数外面包一个立即执行的无参数函数 ,并且把严格模式设定在外层函数。
function doSomething ( a, b = a ) {
'use strict' ;
...
}
const doSomething = function ( { a, b} ) {
'use strict' ;
...
} ;
const doSomething = ( ... a) => {
'use strict' ;
...
} ;
const obj = {
doSomething ( { a, b} ) {
'use strict' ;
...
}
} ;
'use strict' ;
function doSomething ( a, b = a ) {
}
const doSomething = ( function ( ) {
'use strict' ;
return function ( value = 42 ) {
return value;
} ;
} ( ) ) ;
2.rest参数
形式为(…变量名),如...arr
,如果有多个参数,reset只能作为最后一个参数
,否则会报错
function add ( ... values) {
let sum = 0 ;
for ( var val of values) {
sum += val;
}
return sum;
}
add ( 2 , 5 , 3 )
function f ( x, ... y, z ) { ... }
3.name属性
function fn ( ) { }
const res = fn. name
将匿名函数赋值给一个变量,ES5返回的是空字符串,而ES6返回实际的函数名
const fun = function ( ) { }
const res = fun. name
将具名函数赋值给一个变量,返回的是函数原本的函数名
const foo = function fn ( ) { }
const res = foo. name
4.箭头函数
使用箭头(()=>)定义函数,括号代表参数部分,参数可以零个或多个,箭头后面代表返回值
const res = n => n * 2
const res = function ( n ) { return n * 2 }
如果返回值超过一行,需要用花括号{}包起来,并且加上return,没写的话默认return:undefined
const mul = ( n, m ) => {
const count = n + m
return count
}
console. log ( mul ( 3 , 6 ) ) ;
let foo = ( ) => { a: 1 }
let foo = ( ) => ( { a: 1 } )
const foo = ( { firstName, lastName } ) => ` ${ firstName} - ${ lastName} `
const res = foo ( { firstName: 'Vincent' , lastName: 'William' } )
const numbers = ( ... nums) => nums
const res = numbers ( 1 , 2 , 3 , 4 , 5 )
const fn = ( first, ... other ) => [ first, other]
const res = fn ( 1 , 2 , 2 , 4 , 5 , 6 )
*
箭头函数的注意点: 1、箭头函数没有自己的this,函数体内的this对象是定义时所在的对象(它在声明的时候可以捕获其所在上下文的this供自己使用),也就是说箭头函数的this指向的是函数声明时所在的上下文。 2、在普通函数中this的指向是可变的,但是在箭头函数中它是固定的,call()、apply()、bind()对于箭头函数没有效果。 3、箭头函数不能用于构造函数,不能使用new命令,否则会抛出一个错误,因为new内部有改变this指向的操作。 4、不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用rest参数代替。 5、不可以使用yield命令,因此箭头函数不能用作Generator函数。 6、箭头函数不具有prototype原型对象,也因此不能被new,因为new内部需要调用函数的prototype属性。
5.尾调用优化
目前只有Safari浏览器支持尾调用优化,所以先了解一下就好了。 尾调用(Tail Call)是指在函数的最后一步调用另一个函数。 关于尾调用优化参考:尾调用优化
function fn ( ) {
return g ( )
}
以下情况不属于尾调用:
function f ( x ) {
let y = g ( x) ;
return y;
}
function f ( x ) {
return g ( x) + 1 ;
}
function f ( x ) {
g ( x) ;
}
function addOne ( a ) {
var one = 1 ;
function inner ( b ) {
return b + one;
}
return inner ( a) ;
}
6.尾递归
function factorial ( n ) {
if ( n === 1 ) return 1 ;
return n * factorial ( n - 1 ) ;
}
const res = factorial ( 5 )
function factorial ( n, total = 1 ) {
if ( n === 1 ) return total
return factorial ( n - 1 , total * n)
}
const res = factorial ( 5 )
console. log ( res) ;
7.函数参数的尾逗号
如下例子,函数每个参数独占一行,之后要添加参数的话,势必要在原来的最后一个参数后面加一个逗号,这样对于版本管理系统来说,会显示添加逗号的那行也发生了变化,看上去有点冗余。因此,新的语法允许定义和调用的时候,尾部直接有一个逗号。
function fn (
param1,
param2
)
function fn (
param1,
param2,
)
8.Function.prototype.toString()
函数的toString()
方法返回函数代码本身。ES2019以前,会忽略空格和注释;ES2019后会返回所有的原始代码。
function foo ( ) { }
foo. toString ( )
function foo ( ) { }
foo. toString ( )
9.catch参数可省略
try {
} catch ( err) {
}
try {
} catch {
}