ES6标准关于函数部分的扩展,主要涉及以下几个方面:

1)函数参数默认值

2)函数参数解构赋值

3)函数剩余参数rest参数

4)箭头函数

5)关于严格模式

1.函数参数默认值

1)在ES6之前不能为函数的参数指定默认值,

ES6允许为函数的参数设置默认值(即参数值直接写在参数定义的后面)

es js 自定义函数引用_作用域

es js 自定义函数引用_默认值函数声明时作用域_02

2)参数变量是默认声明的,不能用let const再次声明

es js 自定义函数引用_函数参数默认值_03

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

es js 自定义函数引用_es js 自定义函数引用_04

4)通常情况下定义默认值的参数应该是函数的尾部参数,如果非尾部参数设置默认值,这个参数不能省略

函数参数设定默认值当传入的是undefined会输出原来的默认值,如果传入的是null 就没有此功能

es js 自定义函数引用_ES6_05

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

由于函数的length属性是指该函数预期传入的参数个数,某个参数指定默认值后预期传入的参数就不包括这个参数

如果设置了默认值的参数不是尾部参数,length也不计入后面的参数

es js 自定义函数引用_es js 自定义函数引用_06

6)设置了参数的默认值,函数进行声明初始化,参数会形成一个单独的作用域context,初始化结束作用域消失

不设置参数默认值时,不会出现作用域。(声明时作用域)

es js 自定义函数引用_默认值函数声明时作用域_07

根据上面的demo我们来分析这四条输出语句。在分析前,我们回顾一下“函数内变量提前声明”和“函数作用域”的概念,

es js 自定义函数引用_作用域_08

蓝色箭头表示变量作用域链,在此基础上我们分析每个结果的由来

1:函数体内声明了与参数同名的变量x,此时根据“变量声明提前”原则,函数作用域内x的声明被提前到function头部,参数x也是无默认值传递给它,所以函数内x是Undefined

2:

3:函数体内声明了与参数x同名的变量x ,但变量x 与参数x没有任何关系,只存在一个初始化赋值的操作,此时输出的变量x既进行了声明也进行了赋值所以输出3

4:全局变量x和上述两个作用域都没有关系,不会被改变。在函数外部定义的变量,在函数内部执行代码时,是无法获取外部变量的值。

接着我们再来看一个例子,有助于加深对“有默认值的函数声明时作用域”和“函数作用域的关系”:

es js 自定义函数引用_es js 自定义函数引用_09

运行结果分析如下:

在函数fun1()中,因为参数有默认值,所以参数开辟了自己的作用域,函数体内声明了自己的变量x ,也开辟了自己的作用域,但是这两x没有任何关系,只是参数x用自己的值初始化了函数体内的x,所以第一个输出1,调用函数y(),在函数y()内先声明了x=2,再输出当然就是2了,

在函数fun2()中,函数体内未声明自己的同名变量,在变量解析的时候就会沿着“作用域链”找到参数声明作用 域内,此时访问的时候就是访问参数声明作用域内的x。

总结:

1)有默认值的函数,开辟了单独的“参数声明作用域A”,这个作用域域函数体内的作用域是互不相干的,独立的

2)函数体内的同名变量接受来自同名参数的默认赋值,并单独开辟函数体内的一个作用域B

3)在作用域B中找不到变量时,程序会沿着作用域链,找到作用域A中的变量,并加以操作。