ES6中函数的扩展(函数参数默认值)

ES6允许为函数的参数设置默认值,即直接写在参数定义的后面。

function log(x,y='World'){
    console.log(x,y);
}
log('Hello');/*Hello World*/
log('Hello','China');/*Hello China*/
log('Hello','');/*Hello*/
function Point(x=0,y=0){
    this.x = x;
    this.y = y;
}
const p = new Point();
p/*{x:0,y:0}*/

参数变量是默认声明的,所以不能在函数体中再次声明;

参数默认值可以与解构赋值的默认值结合起来使用:

function fetch(url, { body = '', method = 'GET', headers = {} }){
    console.log(method);
}
fetch('http://example.com',{});/*GET*/
fetch('http://example.com');/*报错*/

上述函数fetch的第二个参数是一个对象,可以为三个属性设置默认值;这种写法不能省略第二个参数,否则会报错;

但如果结合函数参数的默认值,就可以省略第二个参数(双重默认值)如下:

function fetch(url, { body = '', method = 'GET', headers = {} } = {}){
    console.log(method);
}
fetch('http://example.com');/*GET*/

定义了默认值的参数,应该是函数的尾参数,如果非尾部的参数设置默认值,实际上这个参数无法省略(如下):

function f( x, y = 5, z ){
    return [x, y, z];
}

f(); /*[undefined, 5, undefined]*/
f(1); /*[1, 5, undefined]*/
f(1, ,2); /*报错*/
f(1, undefined, 2); /*[1, 5, 2]*/
f(1, null, 2); /*[1, null, 2]*/

参数默认值位置

上述代码中,有默认值的参数都不是尾参数,

可全部省略(如上第一条);

可省略有默认值参数的参数以及后边的参数(如上第二条);

若只省略有默认值的参数,则会报错(如上第三条);

这时无法只省略该参数,而不省略他后边的参数,除非显示输入undefined;因为如果传入undefined,将触发该参数等于默认值(如上第四条);

null不可以(如上第五条)。

函数的length属性

(function(...args) {}).length:将返回没有指定默认值的参数个数,但如果设置了默认值的参数不是尾参数,则length属性也不再计入后边的参数了。

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

(function (a) {}).length  /*1*/
(function (a = 5) {}).length  /*0*/
(function (a, b, c = 5) {}).length  /*2*/
(function (a = 5, b, c) {}).length  /*0*/

(function (...a) {}).length  /*0   rest参数*/

作用域

一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域;

等初始化结束,这个作用域会消失;

var x = 1;
function f(x, y = x){
    console.log(y);
}
/*参数y的默认值等于变量x,调用函数f时,参数形成一个单独的作用域,在这个作用域中,默认值变量x指向第一个参数x,而不是全局变量x*/
f(2);//2
let x = 1;
function f(y = x){
    let x = 2;
    console.log(y);
}
/*参数y的默认值等于x,调用函数f时,参数 y = x 形成一个单独的作用域,在这个作用域中,变量x本身没有定义,所以指向全局变量x*/
/*函数调用时,函数体内部的局部变量x影响不到默认值变量x*/
f();

猜你喜欢

转载自blog.csdn.net/weixin_41813970/article/details/86606933