函数形参的默认值

ES6之前函数形参的默认值设置

当前一个操作数值为false时,总会返回后一个值。对于函数的命名参数,前一个操作数的值为false时,

总会返回后一个值,对于函数的命名参数,如果不显示传值,则其值默认为undefined,但是这个方法有缺陷

当我们为timeout传入0时,即使这个值为合法的,boolean判断仍为false

在这种情况下,更安全的是使用typeof

 ES6 函数参数默认值

在这个函数中,只有第一个参数被认为是总要为其传入值的,其他两个参数都有默认值,而且不需要添加任何校验值是否缺失的代码

makeRequest("/foo")  // 使用参数timeout和callback的默认值

makeRequest("/foo", 500);  // 使用参数callback的默认值

makeRequest("/foo", 500, function(body){doSomething(body)});  // 不使用默认值

按照ES6写法,url是必需参数,声明函数时,可以为任意参数指定默认值,在已指定默认值的参数后可以继续声明无默认值参数,例如:

在这种情况下,只有当不为第二个参数传入值或主动为第二个参数传入undefined时才会使用timeout的默认值,

makeRequest("/foo", undefined, function(body){doSomething(body);});  // 使用timeout默认值

makeRequest("/foo"); // 使用timeout默认值

makeRequest("/foo", null, function(body){doSomething(body);});  // 不使用timeout默认值

对于默认参数值,null也是一个合法值

默认参数值对arguments对象的影响

(1)ES5 非严格模式下

  

在非严格模式下,命名参数的变化会同步更新到arguments对象中

(2)ES5 严格模式下

  

无论命名参数如何变化,arguments对象将不再随之改变,始终等于调用函数时传入的参数值(即["a", "b"])

(3)ES6 中

ES6 中,如果一个函数使用了默认参数值,则无论是否显示定义了严格模式,arguments对象的行为都将和ES5 严格模式下一致。

默认参数值的存在使得arguments对象保持与命名参数分离

只给函数传递一个参数在,则arguments[0] 值为 "a",arguments[1] 值为undefined,arguments.length为1;改变first 和second  不会影响arguments。

所以总是可以通过arguments对象将参数恢复为初始值

默认参数表达式

在上述代码中,如果不传入最后一个参数,就会调用getValue()函数来得到正确的默认值

注意:初次解析函数不会调用getValue()方法,当调用add()方法且不传入第二个参数时才会调用

   当使用函数调用结果作为默认值时,如果忘记写小括号,传入的将是对函数的引用,而不是函数调用结果

因为默认参数是在函数调用时求值,所以可以使用先定义的参数作为后定义参数的默认值

还可以将first的值传入一个函数来获得second的值

在引用参数默认值的时候,只允许引用前面参数的值,即先定义的参数不能访问后定义的参数。

默认参数的临时死区

回顾上述例子,当调用add(1,1)时,相当于执行以下代码:

let first = 1;

let second = 1;

调用add(1)时,

let first = 1;

let second = getValue(first);  //  first 已经从临时死区中解放出来了

上述代码:

调用add(1,1)时,

let first = 1;

let second = 1;

调用add(1)时,

let first = second;  // 出错,因为此时second还处于临时死区中

let second = 1;  

函数参数有自己的作用域和临时死区,和函数体的作用域是独立的,就是说函数参数默认值不能访问函数体内声明的变量

猜你喜欢

转载自www.cnblogs.com/aizzz/p/9790017.html