2020-09-20 函数的扩展

函数的扩展

           函数参数的默认值基本用法:

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

(1)

```

           (2)与解构赋值默认值结合使用

(2)

```

           (3)参数默认值的位置 

       通常情况下,定义了默认值的参数,应该是函数的尾参数。因为这样比较容易看出来,到底省略了哪些参数。如果非尾部的参数设置默认值,实际上这个参数是没法省略的。

(3)例一
(3)例二

```

           (4)函数的 length 属性

        指定了默认值以后,函数的`length`属性,将返回没有指定默认值的参数个数。也就是说,指定了默认值后,`length`属性将失真。

        (function (a) {}).length   // 1

        (function (a = 5) {}).length   // 0

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

(4)

```

       - fn.length 返回形参个数

       - arguments.length 返回实参个数

            (5)作用域

       一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域。等到初始化结束,这个作用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。

5.1

       5.1代码中,参数`y`的默认值等于变量`x`。调用函数`f`时,参数形成一个单独的作用域。在这个作用域里面,默认值变量`x`指向第一个参数`x`,而不是全局变量`x`,所以输出是`2`。

```

5.2

        5.2代码中,函数`f`调用时,参数`y = x`形成一个单独的作用域。这个作用域里面,变量`x`本身没有定义,所以指向外层的全局变量`x`。函数调用时,函数体内部的局部变量`x`影响不到默认值变量`x`。

```

5.3

       5.3代码中,参数`x = x`形成一个单独作用域。实际执行的是`let x = x`,由于暂时性死区的原因,这行代码会报错”x 未定义“。

```

5.4

        5.4如果将`var x = 3`的`var`去除,函数`foo`的内部变量`x`就指向第一个参数`x`,与匿名函数内部的`x`是一致的,所以最后输出的就是`2`,而外层的全局变量`x`依然不受影响。


5.5

```


            (6)rest 参数 

        ES6 引入 rest 参数(形式为`...变量名`),用于获取函数的多余参数,这样就不需要使用`arguments`对象了。rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

`arguments`对象不是数组,而是一个类似数组的对象。所以为了使用数组的方法,必须使用`Array.prototype.slice.call`先将其转为数组。rest 参数就不存在这个问题,它就是一个真正的数组,数组特有的方法都可以使用。下面是一个利用 rest 参数改写数组`push`方法的例子。

         注:rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。

                    // 报错

                    function f(a, ...b, c) {

                           // ...

                    }

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

                 (function(a) {}).length  // 1

                 (function(...a) {}).length  // 0

                 (function(a, ...b) {}).length  // 1

```

           (7)严格模式

                    从 ES5 开始,函数内部可以设定为严格模式。ES2016 做了一点修改,规定只要函数参数使用了默认值、解构赋值、或者扩展运算符,那么函数内部就不能显式设定为严格模式,否则会报错

          (8)name 属性 

                   返回函数名:

                           function foo() {}

                           console.log(foo.name)   //  foo

                           var f = function () {};

                           console.log(f.name)   //  f

```

            (9)箭头函数基本用法

                 ES6 允许使用“箭头”(`=>`)定义函数。

                 例如:var fn = v => v;   箭头函数等同于:var fn = function(v) {return v;};

               注:如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。

```

       如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用`return`语句返回。

        var sum = (num1, num2) => { return num1 + num2; }

```

       由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号,否则会报错。

        // 报错

        let getTempItem = id => { id: id, name: "Temp" };

        // 不报错

       let getTempItem = id => ({ id: id, name: "Temp" });

```

箭头函数使用注意点:

1. 函数体内的`this`对象,就是定义时所在的环境,而不是使用时所在的环境。

2. 不可以当作构造函数,也就是说,不可以使用`new`命令,否则会抛出一个错误。

3. 不可以使用`arguments`对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

4. 不可以使用`yield`命令,因此箭头函数不能用作 Generator 函数。

`this`指向的固定化,并不是因为箭头函数内部有绑定`this`的机制,实际原因是箭头函数根本没有自己的`this`,导致内部的`this`就是外层代码块的`this`。正是因为它没有`this`,所以也就不能用作构造函数。

箭头函数转成 ES5 的代码如下:

转换后的 ES5 版本清楚地说明了,箭头函数里面根本没有自己的this,而是引用外层的this。

```

由于箭头函数没有自己的`this`,所以当然也就不能用`call()`、`apply()`、`bind()`这些方法去改变`this`的指向。

```

          (10)函数参数的尾逗号

             ES2017 [允许](https://github.com/jeffmo/es-trailing-function-commas)函数的最后一个参数有尾逗号(trailing comma)。

       这样的规定也使得,函数参数与数组和对象的尾逗号规则,保持一致了。

```
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容