第十章 函数篇(二)(JavaScript高级程序设计-读书笔记)

    科技2022-07-10  115

    关于函数参数:


    1.理解参数:

    ECMAScript函数既不关心传入的参数个数,也不关心这些参数的数据类型。

    定义函数时要接收两个参数,并不意味着调用时就传两个参数,可以传一个、三个,甚至一个也不传,解释器都不会报错。

    之所以会这样,主要是因为ECMAScript函数的参数在内部表现为一个数组。函数被调用时总会接收一个数组,但函数并不关心这个数组中包含什么,数组中没有元素或者元素超出了要求,也没问题。

    事实上,在使用function关键字定义(非箭头)函数时,可以在函数内部访问arguments对象,从中取得传进来的每个参数值。

    argument对象:是一个类数组对象(非Array的实例),因此可以使用中括号语法访问其中的元素(第一个参数是arguments[0],第二个参数是arguments[1])。而要确定传进来多少个参数,可以访问arguments.length属性。

    在下面的例子中,sayHi()函数的第一个参数叫name:

    function sayHi(name, message) { console.log("Hello " + name + "," + message; }

    可以通过arguments[0]取得相同的参数值。因此把函数重写成不声明参数也可以:

    function sayHi() { console.log("Hello " + arguments[0] + "," + arguments[1]; }

    上述例子表明:ECMAScript函数的参数只是为了方便才写出来的,并不是必须写出来的。与其他语言不同,在ECMAScript中的命名参数不会创建让之后的调用必须匹配的函数签名,这是因为根本不存在验证命名参数的机制。

    (函数签名:接收参数的类型和数量)

    在函数中,arguments对象可以跟命名参数一起使用,比如:

    function doAdd(num1, num2) { if (arguments.lenght == 1) { console.log(num1 + 10); } else if (arguments.length == 2) { console.log(arguments[0] + num2); } }

    arguments对象的值始终会与对应的命名参数同步,但这种同步是单向的,修改命名参数的值,不会影响arguments对象中对应的值。

    arguments对象的长度是根据传入的参数个数,而非定义函数时给出的命名参数个数确定的。

    严格模式下,arguments会有一些变化,首先修改arguments对象中的值,不会改变对应的命名参数的值。其次,在函数中尝试重写arguments对象会导致语法错误(代码也不会执行)。

    如果函数是使用箭头语法定义的,那么传给函数的参数将不能使用arguments关键字访问,而只能通过定义的命名参数访问。


    2.没有重载:

    ECMAScript函数不能像传统编程那样重载,如前所言,ECMAScript函数没有签名,因为参数是由包含零个或多个值的数组表示的,没有函数签名,自然也就没有重载。

    如果在ECMAScript中定义了两个同名函数,则后定义的会覆盖先定义的。


    3.默认参数值:

    ECMAScript 6之后,函数支持显式定义默认参数,只要在函数定义中的参数后面用=就可以为参数赋一个默认值。

    function addNum(num = 100) { return num + 100; } console.log(addNum(200)); //300 console.log(addNum()); //200

    在使用默认参数时,arguments对象的值不反映参数的默认值,只反映传给函数的参数。修改命名参数也不会影响arguments对象,它始终以调用函数时传入的值为准。

    参数初始化顺序遵循“暂时性死区”规则,即前面定义的参数不能引用后面定义的。


    4.参数拓展:

    ECMAScript 6 新增了拓展操作符,使用它可以非常简洁的操作和组合集合数据,既可以用于调用函数时传参,也可以用于定义函数参数。

    let value = [1, 2, 3, 4]; console.log(...value); //1 2 3 4

    使用拓展操作符传参时,arguments对象也可以接收每一个值。

    在普通函数和箭头函数中,也可以将拓展操作符用于命名参数,同时也可以使用默认参数。

    Processed: 0.014, SQL: 8