ECMAScript 6 笔记(7)- 函数的扩展(1)

原创 乘风逐月 随笔 ES6 157阅读 2018-08-28 15:26:20 举报

阅读原文: 阮一峰:ECMAScript 6 入门

一、函数参数的默认值

1.基本用法
2.注意问题

(1)参数变量是默认声明的,在函数体内,不能用 let 或 const 再次声明,否则会报错。

(2)使用参数默认值时,函数不能有同名参数。

(3)参数默认值不是传值的,而是每次都重新计算默认值表达式的,即参数默认值是惰性求值的。

二、参数默认值与解构赋值默认值结合使用

1.基本用法

上例中,只使用了对象的解构赋值,没有使用函数参数的默认值。只有当 foo 函数的参数是一个对象时,变量 x 和 y 才会通过解构赋值生成。
如果函数 foo 调用时没有提供参数, 变量 x 和 y 就不会生成,从而报错。通过提供函数参数的默认值,可以避免这种情况。

2.参数默认值与解构对象的默认值

上例中两种写法的区别是:
a. 写法一: 参数的默认值是一个空对象,但设置了解构对象的两个属性默认值
b. 写法二: 参数的默认值是一个有具体属性的对象,但没有设置解构对象的属性默认值

三、参数默认值的位置

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

上例中,有默认值参数不是尾参数的,这时无法只省略该参数,而不省略它后面的其他参数,除非显式输入 undefined。
如果输入 undefined,将触发该参数等于默认值,null则没有这个效果。

四、函数的 length 属性

指定了默认值后,函数的 length 将返回没有指定默认值的参数个数。即指定了默认值后,length 属性将失真。

上例中,length 的返回值是函数的参数个数减去指定了默认值的参数个数。这是因为 length 属性的含义,该函数预期传入的参数的个数。某个参数指定了默认值后,预期传入的参数个数就不包括这个参数了。
注:
如果指定了默认值的参数不是尾参数,那么该参数后面的参数也不计入 length 属性了。

五、参数作用域

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

上例中, 函数 f 调用时, 参数 y = x 形成一个单独的作用域。这个作用域里面,变量 x 本身没有定义,所有指向外层的全局变量 x。 函数调用时,函数体内部的局部变量 x 影响不到默认值变量 x 。
此时,如果全局变量 x 不存在,就会报错。

这样写也会报错:

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

六、rest 参数

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

注:
a. rest 参数之后不能再有其他参数,否则会报错。
b. 函数的 length 属性不包括 rest 参数。

七、严格模式

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

这样规定的原因是,函数内部的严格模式,同时适用于函数体和函数参数。但是,函数执行的时候,先执行函数参数,然后再执行函数体。这样就有不合理的地方,只有执行到函数体才知道是否该以严格模式执行,但是参数却先与函数体执行。

两种方法可以规避这种限制:
a. 第一种:设置全局性的严格模式

b. 第二种:把函数包在一个无参数立即执行的函数里面

八、name 属性

函数的 name 属性,返回该函数的函数名。
ES6将其写入标准,作出了修改:
a. 如果将一个匿名函数赋值给一个变量,ES5的 name 属性会返回空字符串。ES6的 name 属性会返回实际的函数名。

b. 如果将一个具名函数赋值给一个变量,则ES5和ES6的属性都会返回这个具名函数原本的名字。

c. Function 构造函数返回的函数实例,name 属性的值为 anonymous

d. bind 返回的函数,name 属性值会加上 bound 前缀

评论 ( 1 )
最新评论