3、函数

第三章、函数


1、函数形参可以指定默认值,并且默认值所在的形参不会自动添加到arguments对象中。

2、函数形参可以用表达式作为默认值,也可以用先定义的形参作为后定义的形参的默认值,
    但不能用后定义的形参作为先定义的形参的默认值,否则会进入函数默认参数的临时死区。
    
3、函数参数有自己的作用域和临时死区,其与函数体的作用域是各自独立的,即参数的默认值不可访问函数体内声明的变量。

4、函数形参使用不定参数接收额外的不确定的参数。
        1、不定参数的使用限制:
                ①、每个函数只能声明一个不定参数,而且一定要放在最后
                ②、不定参数不能用于对象字面量setter之中,因为对象字面量setter的参数有且只能有一个。
                
        2、不定参数对arguments的影响:无论是否使用不定参数,arguments对象总是包含所有传入函数的参数。
        
5、展开运算符:与不定参数恰好相反。不定参数将多个参数收纳进类数组对象中,展开运算符将类数组对象的各项打散展开。

6、函数name属性的特殊情况:
        1、getter函数的name属性带有前缀"get",setter函数的name属性带有前缀"set"
        2、通过bind()函数创建的函数,其name属性带有前缀"bound"
        3、通过Function构造函数创建的函数,    其name属性是"anonymous"
        切记:不能使用name属性的值来获取对于函数的引用
        
7、函数的多重用途:通过new关键字调用或直接调用
        原因:
                JavaScript函数有两个不同的内部方法:[[call]]和[[Construct]]
                当通过new关键字调用函数时,执行的是[[construct]]函数,它负责创建一个被称作实例的新对象,然后载执行函数体,
        将this绑定动实例上;如果不通过new关键字调用函数,则执行[[call]]函数,从而直接执行函数体。
                具有[[construct]]方法的函数被称为构造函数。
        切记:不是所有的函数都有[[construct]]方法,即不是所有函数都能用new关键字调用(例如箭头函数)。
        
        判断函数是否通过new关键字调用:
                判断new.target的值
                如果函数是通过new关键字调用的,new.target的值是实例化的新对象;如果不是,new.target的值为"undefined"
                
8、块级函数:
        在代码块中声明块级函数,函数声明会被提升至块的顶部,而用let定义的函数表达式不会被提升。
        
9、箭头函数:
        箭头函数特性:
            1、没有this、super、arguments和new.target绑定
                    箭头函数中的this、super、arguments和new.target这些值由外围最近一层的非箭头函数决定。
            2、不能通过new关键字调用
                    箭头函数没有[[construct]]方法,所以不能被用作构造函数,如果通过new关键字调用函数,程序报错。
            3、没有原型
                    由于不能通过new关键字调用箭头函数,所以箭头函数没有prototype这个属性。
            4、不可以改变this的绑定
                    箭头函数内部的this值不可以被改变,在函数的生命周期内始终保持一致。
            5、不支持arguments对象
                    箭头函数没有arguments绑定,所以只能通过命名参数和不定参数两种形式访问函数的参数。
            6、不支持重复的命名参数
                    箭头函数不支持重复的命名参数。        
            注意:箭头函数同样也有name属性!


10、尾调用优化
        尾调用:函数作为另一个函数的最后一条语句被执行。
        es5中尾调用如正常函数调用一样,创建一个栈帧并将其推入调用栈,即未调用完成的栈帧都保存在内存中,
        如果调用栈过大就会导致程序出现问题。
        es6严格模式下尾调用自动优化:如果满足以下条件,将不再创建新的栈帧,而是清除并重用当前栈帧:
            1、尾调用不访问当前栈帧的变量,即函数不是一个闭包。
            2、在函数内部,尾调用是最后一条语句。
            3、尾调用的结果作为函数值返回。
        尾调用优化主要应用在递归函数,例如以下阶乘:
            function factorial(n){
                if(n <= 1){
                    return 1;
                }else{
                    return n * factorial(n-1);
                }
            }
            上面这个阶乘,引擎就不会自动优化,因为在返回结果后执行了乘n操作,优化如下:
            function factorial(n,r=1){
                if(n <= 1){
                    return 1* r;
                }else{
                    return factorial(n-1,r);
                }
            }

发布了247 篇原创文章 · 获赞 23 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/LiyangBai/article/details/102974363