JS Function类型总结以及ES6中函数的扩展

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_37473645/article/details/89606385

一、Function类型总结

1、函数实际上是对象。

        每个函数都是Function类型的实例,而且都与其他引用类型一样具有属性和方法。函数是一个指向函数对象的指针。

2、函数没有重载。

3、使用 函数声明语法 定义,可以在代码开始前执行。使用 函数表达式 必须等到解释器执行到它所在的代码行,才会真正被解释执行。

4、函数名本身就是变量,所以函数可以作为值来使用。

5、在函数内部,有两个特殊对象:arguments this。

        arguments:类数组对象,包含着传入函数中的所有参数。

        this:this引用的是函数执行的环境对象。

6、每个函数包含两个属性 length prototype

        length:表示函数希望接收的命名参数的个数。

        prototype:保存引用类型所有实例方法的真正所在。

7、每个函数都包含两个非继承而来的方法:apply()call()

        用途:在特定的作用域中调用函数,实际上等于设置函数体内this对象的值。能够扩充函数赖以运行的作用域。       

        好处:使用call()和apply()扩充作用域,对象不需要与方法有任何耦合关系。

函数.apply( 运行函数的作用域 , 参数数组 )

函数.call( 运行函数的作用域 , 参数必须逐个列举出来 )

8.ES5还定义了一个方法:bind()

        bind():该方法会创建一个函数的实例,其this值会被绑定到传给bind()函数的值。

        用途:主要用于事件处理程序以及setTimeout()和setInterval()。

        注意:被绑定函数与普通函数相比有更多的开销,它们需要更多内存,同时也因为多重函数调用稍微慢一点,所以最好只在必要时使用。

windows.color = "red";
var o = { color: "blue"};

function sayColor(){
    console.log(this.color);
}

var objectSayColor = sayColor.bind(o); //注意这里返回的是一个函数
objectSayColor();

二、函数的扩展

1、函数参数的默认值

        ①基本用法:直接写在参数后面。

function log(x,y='world'){
       console.log(x,y);
}
log('Hello'); //=>Hello world
log('Hello','yujinhong'); //=>Hello yujinhong
log('Hello','');// =>Hello 

        ②与解构赋值默认值结合使用

function foo({x,y=5}){
    console.log(x,y);
}
foo({}); //=>undefined 5
foo({x:1}); //=>1 5
foo({x:1,y:2}); //=>1 2
foo(); //=>Uncaught TypeError: Cannot destructure property `x` of 'undefined' or 'null'.

        ③参数默认值的位置

        通常情况下,定义了默认值的参数应该是函数的尾参数。

        ④函数的length属性

         函数的length属性返回没有指定默认值的参数个数。如果设置了默认值的参数不是尾参数,那么length属性也不再计入后面的参数。

        ⑤作用域

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

        ⑥应用

        利用参数默认值可以指定某个参数不得省略,如果省略就抛出一个错误。

function throwIfMissing(){
    throw new Error('Missing parameter');
}
function foo(mustBeProvided = throwIfMissing()){
    return mustBeProvided;
}
console.log(foo()); //=>Uncaught Error: Missing parameter at throwIfMissing

2、rest参数

        ES6引入了rest参数(形式为:“...变量名”),用于获取函数多余的参数,这样就不需要arguments。

function add(...values){
    let sum = 0;
    for(var val of values){
        sum += val;
    }
    return sum;
}
console.log(add(2,3,3)) //=>8

        注意:rest参数后不能有其他参数,否则报错。

3、严格模式

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

        规避方法:①设定全局性的严格模式。②把函数包在一个无参数的立即执行函数里面。

4、name属性

        函数的name属性返回该函数的函数名。ES5返回空字符串,ES6返回实际的函数名。

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

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

5、箭头函数

        ①基本用法:

        A、有一个参数,箭头函数的代码块部分只有一条语句

var f = v => v;

        B、没有参数或需要多个参数,就要使用圆括号代表参数部分

var f = () => 5;
var sum = (num1,num2) => num1+num2;

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

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

        D、如果箭头函数直接返回一个对象,必须在对象外面加上括号

var getTempItem = id => ({id: id,name: "yujinhong"});

        ②注意事项

        A、函数体内的this对象就是定义时所在的对象,而不是使用时所在的对象。

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

        C、不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用rest参数。

        D、不可以使用yield命令,因此箭头函数不能用作Generator函数。

        E、箭头函数没有自己的this,不能用call()、apply()、bind()这些去改变this的指向。

        ③箭头函数内部还可以使用箭头函数。

6、this绑定

        箭头函数可以绑定this函数,大大减少了显示绑定this对象的写法(call、apply、bind)。

        ES7提出“函数绑定”运算符并排的双冒号(::)。

7、尾调用

        ①尾调用(Tail Call)是函数式编程的一个重要概念,指某个函数的最后一步是调用另一个函数。

        ②尾调用优化:只保留内存函数的调用帧。

        ③尾递归:尾调用自身就叫尾递归。(尾递归永远不会发生“栈溢出”错误)。

        ④递归函数的改写:把所有用到的内部变量改写成函数的参数,即可将递归函数改写成尾递归。

        为直观的可采用的方法有:A、在尾递归函数之外再提供一个正常形式的函数  B、柯里化  C、采用ES6的函数默认值

        ⑤ES6的尾调用优化只在严格模式下开启,正常模式下无效。

        ⑥正常模式下尾递归优化的实现:采用“循环”替换“递归”。

8、函数参数的尾逗号

        ES2017允许函数的最后一个参数有尾逗号。

猜你喜欢

转载自blog.csdn.net/qq_37473645/article/details/89606385