函数
函数参数默认值
- 参数默认值
function fn(x="Nick",y=18){
console.log(x,y);
}
fn(0); // 0 18
fn(); // "Nick" 18
- 参数变量是默认声明的,不能用let或const再次声明。
function foo(){
let x = 1 // error
const x = 2 // error
}
// Uncaught SyntaxError: Identifier 'x' has already been declared
- 使用参数默认值时,函数不能有同名参数。
// 不报错
function foo(x,y){
// ...
}
// 报错 SyntaxError: Duplicate parameter name not allowed in this context
function foo(x,x,y=100){
// ...
}
- 与解构赋值默认值配合使用。
// 此时仅使用了对象解构默认值,未提供函数参数默认值
function fn1({name,age=18}){
console.log(name,age);
}
fn1({}) // undefined 18
fn1(); // 此时出错 因为没有传入参数,变量x和y并没有生成。TypeError: Cannot read property 'x' of undefined
// 使用函数参数默认值。
function fn2({name,age=18}={}){
console.log(name,age);
}
fn2(); // undefined 18
// 使用函数参数默认值,未提供对象的解构赋值默认值。
function fn3({name,age}={name:"Nick",age:20}){
console.log(name,age);
}
fn3(); // Nick 20
- 参数默认值的位置 一般而言,定义了默认值的参数,应该是函数的尾参数。如果非函数尾参数设置默认值,则这个参数无法省略。
// 例子一
function f(x=1,y){
return [x,y]
}
f() // [1,undefined]
f(2) // [2,undefined]
f(,1) // 编辑器报错
f(undefined,1) // [1,1]
// 例子二
function f(x,y=5,z){
return [x,y,z]
}
f() // [undefined,5,undefined]
f(1,,3) // 编辑器报错
f(1,undefined,5) // [1,5,5]
// 传入undefined会触发默认参数值,传入null不会触发,即会将参数赋值为null。
function f(x, y = 5, z=6) {
return [x, y, z]
}
f(1,null,5) // [1,null,5]
- 函数的length属性 函数参数指定了默认值之后,函数的length属性将返回没有指定默认值的参数个数。即,指定默认值之后,length属性将失真。
console.log((function(a){}).length) // 1
console.log((function(a=5){}).length) // 0
如果设置了默认值的参数不是尾参数,则具有默认值参数后的参数均不计入length属性。
console.log((function(a=1,b,c){}).length) // 0
console.log((function(a,b=0,c){}).length) // 1
- 参数默认值的应用 利用参数默认值,可以指定某一个参数不得省略,如果省略就抛出一个错误。
function throwIfMissing(){
throw new Error('Missing paramter')
}
function foo (mustBeProvided = throwIfMissing()){
return mustBeProvided;
}
foo() // Error:Missing parameter
也可将参数默认值设置为undefined,表示此参数可以省略。
function func(parameter = undefined){
// do something
}
rest 参数
ES6引入rest参数(形式为...变量名),用于获取函数的多余参数。rest参数搭配的变量是一个数组,该变量将多余的参数放入数组中。
function fn(...args){
console.log(args); //args是真数组
console.log(arguments); // arguments 是类数组
}
fn();
fuction add(...values){
let sum =0;
for(var val of values){
sum+=val;
}
return sum;
}
add(1,2,3) // 6
rest参数只能是最后一个参数,否则会报错。
// 报错
function foo(a,...b,c){
}
// Uncaught SyntaxError: Rest parameter must be last formal parameter
函数的length属性,不包含rest参数。
console.log((function(a){}).length) // 1
console.log((function(...a){}).length) // 0
严格模式
从ES5开始,函数内部可以设定为严格模式.
function doSomething(a,b){
'use strict';
}
但ES6做了一点修改,只要函数使用了默认值、解构赋值、或者扩展运算符,则函数内部不能显示设为严格模式,否则报错。(此处还有一点。。。内容。)
name属性
函数的name属性,返回该函数的函数名。 这个属性早就被浏览器支持,直到ES6才将其写入标准。 ES6对这个属性的行为作出了修改。一个匿名函数赋值给一个变量,ES5的name属性会返回空字符串,ES6的name属性会返回实际的函数名。
function fn (){}
console.log(fn.name); //fn
console.log((function (){}).name);//""
let f = function(){
}
// ES5
f.name // ""
// ES6
f.name // "f"
将一个具名函数赋值给一个变量,则ES5、6的name属性都返回这个具名函数原本的名字。
let func1 = function func0(){}
console.log(func1.name) // func0
Fucntion构造函数返回的函数实例,其name属性的值为anonymous。
console.log((new Function).name) // anonymous
使用bind返回的函数,name属性值会加上bound 前缀。
function foo(){}
console.log(foo.bind({}).name) // bound foo
(functionn(){}).bind({}).name // bound