美文网首页
【ES6 笔记】函数:参数

【ES6 笔记】函数:参数

作者: ___Jing___ | 来源:发表于2018-10-26 18:03 被阅读0次

不只人类世界,就连编程的世界里也是分三六九等的,呐,函数就是编程世界里的第一等公民。

函数的内容比较多,所以我们分成两篇笔记,本篇主要介绍函数参数相关:参数默认值和无命名参数

参数默认值

  • 函数形参的默认值
    在ES5中,我们有的时候也需要改参数设置一个默认值,做法一般如下:
function defaultParams( arg1, arg2, callback ){
    arg2 = arg2 || 100;
    callback = callback ||function(){};
    console.log(arg1);   // undefined
    console.log(arg2);   //100
    console.log(callback);   //function(){};
}
defaultParams();
* 当我们调用函数时,不传入参数,没有设置默认值的参数,其值为undefined;
* 设置默认值的时候,参数的值为所设置的默认值;
但是,这里有一个隐藏的彩蛋(bug),就是假设arg2我们传入一个数字0时,arg2的参数值会变成100,
0虽然是合法值,但是逻辑运算却是false...
可以将代码修改为arg2 =(typeof arg2!=='undefined') || 100;
这种方法解决了bug,但是却比较繁琐,不符合我们这些有洁癖程序员的习惯...

那么我们现在来看看,ES6中是如何优雅的解决这个问题的~
看ES6的代码:

function defaultParams( arg1, arg2=100, callback=function(){} ){
    console.log(arg1);   // undefined
    console.log(arg2);   //100
    console.log(callback);   //function(){};
}
defaultParams();

怎么样?简洁吧~简直完美!
只需要在定义参数的时候用“=”进行赋值即可。
如果在调用的时候,有传入形参,则为传入的值,如果没有传入,则为“=”右侧所定义的值。
声明函数时,可以喂任意参数指定默认值,在已指定默认值的参数后可以继续声明无默认值参数

  • 默认参数值对arguments对象的影响
    首先,在ES5的非严格模式下,函数命名参数的变化会影响arguments的表现,具体看代码:
//ES5非严格模式
function defaultParamsWithArgs( first, second ){
    console.log( first === arguments[0] );  // true
    console.log( second === arguments[1] );  // true
    first = 1;
    second = 2;
    console.log( first === arguments[0] );   // true
    console.log( second === arguments[1] );  // true
};
defaultParamsWithArgs("a","b");
* 在ES5的非严格模式下,函数体内部对参数值的改变,会同步更新到arguments对象中,
  也就是说你无法断定参数的初始值是什么样的。

在ES5中的严格模式或是ES6中,修改了arguments的这个令人困惑的行为,也就是说无论参数在函数体内做何种变化,arguments只受参数传递进来的初始值影响。
让我们来看代码:

// ES5 严格模式
function defaultParamsWithStrict( first, second ){
    "use strict";
    console.log( first === arguments[0] );  // true
    console.log( second === arguments[1] );  // true
    first = 1;
    second = 2;
    console.log( first === arguments[0] );   // false
    console.log( second === arguments[1] );  // false    
}
defaultParamsWithStrict("a","b");
* 在ES5的严格模式下,在函数体内修改了形参first, second的值,但是修改后的值和arguments不再一致了,
  这里的arguments仍是函数在调用的时候传进来“a”,“b”。
// ES6 不论是否为严格模式,都和ES5的严格模式保持一致
function defaultParamsWithES6( first, second=3){
    console.log(arguments.length); // 1
    console.log( first === arguments[0] );  // true
    console.log( second === arguments[1] );  // false
    first = 1;
    second = 2;
    console.log( first === arguments[0] );   // false
    console.log( second === arguments[1] );  // false        
}
defaultParamsWithES6('a');
* 在调用defaultParamsWithES6函数时,我们只传入了一个参数first=》“a”,
  second我们设置了默认参数3,并且又在函数体内将其修改为了2,
  但是你会发现,我们运行的结果arguments的length属性值为1,并且只有first的值和arguments[0]的值全等。
  这就是ES6中对arguments做的修改,arguments在任何时候只受函数调用时传入的参数初始值影响,
  函数的参数默认值和在函数体内对参数做的修改,都不会改变arguments的初始状态。
  • 默认参数表达式
    有了参数默认值,我们就可以做很多有趣的事情了。
    参数不但可以使用默认值,还可以使用默认表达式(函数)。
    话不多说,上菜(看代码~):
function defaultValue(){
    return 5;
}
function add( first, second=defaultValue()){
  return first + second;
}
console.log( add(1,1) ); //2
// *当我们传递两个参数时,second设置的默认表达式就被覆盖了,此时结果是1+1=2
console.log( add(1) );  //6
// *当我们只传递一个参数的时候,second调用默认表达式,即函数defaultValue()运行的结果 5,结果是1+5=6

注意,这里设置默认表达式时,函数是有调用的()小括号的,有小括号的时候我们的得到的是默认表达式运行以后的返回值,没有这个括号的时候,我们得到的是对函数的引用,意义是不一样的~
由于默认表达式只有在调用的时候才会解析,所以我们还可以使用先定义得到参数作为后定义参数的默认值:

function defaultValue(value){
    return value;
}
function add( first, second=defaultValue(first)){
  return first + second;
}
console.log( add(2,2) ); //4
console.log( add(2) ); //4

在引用参数默认值的时候,值允许引用前面的参数的值,即先定义的参数不能访问后定义的参数,否则会抛出错误,原因请参考临时死区

function defaultValue(value){
    return value;
}
function add( first, second=defaultValue(first)){
  return first + second;
}
console.log( add(2,2) ); //4
console.log( add(2) ); //4

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

  • 处理无命名参数
    我们知道在JS中,无论函数定义了多少参数,在调用的时候都不限制实际传参的数量,但是很多时候我们未必能穷举所有的参数,不注明参数的话,可读性又比较差,ES6为此提供了不定参数解决这个问题。
    语法:在函数的命名参数前添加三个点(...)就表明这是一个不定参数,该参数为一个数组,包含着自它之后传入的所有参数,通过这个数组名即可逐一访问里面的参数。
function checkArgs(param,...keys){
    console.log(checkArgs.length);  // 1  
    //函数的length属性只统计函数命名参数的数量,不定参数的加入不影响其值

    console.log(arguments.length); // 3
    // arguments 对象包含了所有传入的参数的个数

    console.log(keys.length);   //2
    //不定参数的个数

    console.log(keys) ; // ['a','b','c']
    //不定参数的内容  是一个数组
    console.log(keys[0],arguments[1]) //a a
    // 不定参数 和 arguments的对应关系,假设没有param参数的传入,则是对应索引值
   // 函数定义了不定参数时,在函数被调用时,arguments对象包含了所有传入的参数
    console.log(keys[1],arguments[2]) //b b
}
checkArgs('a','b','c')

注意:不定参数有两条使用限制:1.每个函数最多只能声明一个不定参数,且只能放在所有命名参数的末尾;2.不定参数不能用于对象字面量setter之中,因为setter的参数有且只有一个,不定参数可以无限多,两个规则冲突则抛出错误。

相关文章

  • 【学习笔记】ES6 标准 - 函数默认参数、箭头函数、剩余参数

    ES6 标准 - 函数默认参数、箭头函数、剩余参数

  • ES6函数的扩展(一)

    参考:ES6入门(阮一峰) 一、ES6为函数设置默认参数 ES6之前不能为函数设置默认参数,ES6新增可以为函数设...

  • ES6函数扩展

    本文只是学习es6的一些简单笔记,详情请看阮一峰的es6入门。 关于函数参数的默认值 什么时候需要为函数参数设置默...

  • ES6 解构赋值 & 模板字符串

    一、函数的默认参数 ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 ES6 允许为函数的参数设...

  • 8.函数的扩展

    1.函数参数的默认值 ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法。 ES6 允许为函数的参数...

  • ES6 写法示例

    匿名函数调用 ES5 ES6 箭头函数 将数组的内容 * 2 ES5 ES6 默认参数 ES5 ES6 不定参数 ...

  • 第七章 函数的扩展

    函数参数的默认值   在ES6之前,不能直接为函数的参数指定默认值,只能采用变通的方法。ES6允许为函数的参数设置...

  • ES6 函数的扩展

    函数参数的默认值 ES6 之前,不能直接为函数的参数指定默认值,只能采用变通的方法 ES6 允许为函数的参数设置默...

  • es6全家桶(二)—— 箭头函数

    es6全家桶(二)—— rest参数、箭头函数 箭头函数 ES6 允许使用“箭头”(=>)定义函数。 var f ...

  • ES6语法——Function的扩展

    一、函数默认参数ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。 ES6中函数默认值需要注意的点有:...

网友评论

      本文标题:【ES6 笔记】函数:参数

      本文链接:https://www.haomeiwen.com/subject/dfhltqtx.html