美文网首页
007_ES6知识点总结(04)函数的拓展

007_ES6知识点总结(04)函数的拓展

作者: maze1943 | 来源:发表于2020-02-20 09:43 被阅读0次

    ES6知识点整理

    [toc]

    04 函数的拓展

    04.1 函数参数的默认值

    ES6支持函数定义时,直接在参数定义后赋予默认值:

    function add(a = 1, b = 1){
        console.log(a + b);
    }
    add();//2
    add(2,3)//5
    add(0)//1
    

    需要注意的是,函数参数默认赋值,所以不能在函数内部使用let和const对参数同名的变量进行重复声明

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

    function foo({x, y = 5}){
        console.log(x,y);
    }
    foo();//TypeError
    foo({});//undefined, 5
    foo({x:1});//1, 5
    foo({x:1, y:2});//1, 2
    

    上例使用了对象的结构赋值

    参数默认值得位置

    非尾部的参数设置了默认值后,其实是无法省略的,或显示的传入undefined等效于使用默认值

    function f(x = 1, y){
        return [x, y];
    }
    f(5)//[5,undefined]
    f(,5)//报错
    f(undefined, 5)//[1, 5]
    

    默认值对函数length属性的影响

    设置了参数默认值之后,函数的length属性将不再包含有默认值的参数,及其之后的参数,同理对rest参数; 因为函数的length属性代表预计传入的参数个数,设置了默认值之后就不再计入length了。而实际参数的个数不受影响(arguments.length)

    function foo(a, b = 1, c){
        return arguments.length;
    }
    foo.length;//1
    foo(1,2,3);//3
    

    参数默认值的作用域

    一旦设置了参数默认值,函数声明初始化时,参数会形成一个单独的作用域,初始化结束则消失。

    let x = 1;
    function foo(x, y = x){
        return y;
    }
    foo(2);//2
    

    以上代码中,参数y使用参数x作为默认值,调用函数foo时,形成一个单独作用域,y的默认值x指向参数x的值,而非全局变量x。

    let x = 1;
    function foo(y = x){
        let x = 2;
        console.log(y);
    }
    foo();//1
    

    此时在参数默认值生成的单独作用域中没有x这个变量的声明,所以指向了全局变量x,而函数体的变量x影响不到参数作用域。

    04.2 rest参数

    ES6中引入了剩余参数,形式为...变量名,用于获取函数剩余的参数,其值为剩余的参数组成的数组。

    function push(array, ...items){
        items.forEach(function(item){
            array.push(item);
        });
        return array;
    }
    push([1,2,3],4,5,6);//[1,2,3,4,5,6]
    

    注意:函数的length属性不包含剩余参数;剩余参数只能是最后一个参数。

    04.3 严格模式

    ES2016中规定,只要使用了函数默认值,解构赋值或者拓展运算符,那么函数内部就不再允许显示设定为严格模式。

    //报错
    function doSomething(a, b = 1){
        'use strict'
        //code
    }
    

    04.4 name属性

    函数的name属性写入ES6标准,并做了一些修改:
    一个匿名函数赋值给一个变量,函数的name属性将返回实际的函数名,而原来的ES5中会返回空字符串。
    若是具名函数,则都将返回具名函数原本的名字。

    04.5 箭头函数

    基本用法

    //箭头函数
    const foo = (a, b) => a + b;
    
    //普通的函数表达式
    const foo = function(a, b){
        return a + b;
    }
    

    萌妹子传授的顺口溜总结了箭头函数的基本语法:
    删掉function关键字,
    加上一个胖箭头,
    没有参数加括号,
    一个参数可选择,
    多个参数逗号分隔,skrskr~

    const foo = (a, b) => a + b;
    //如果=>后的函数体只有一条语句,则这条语句的结果被return
    
    const foo = (a, b) => {a = a + 2; return a * b;}
    //如果=>后的函数体后需要多条语句,则函数体需要用{}包裹,需要返回结果则必须使用return显式返回
    
    const foo = a => a * a;
    //若箭头函数没有参数或有多个参数,则需使用()将参数部分包裹起来,否则不需要
    

    需要注意的地方

    1. 箭头函数的this指向定义时所在的对象,而不是调用时的对象
    2. 不可以当做构造函数,即不能使用new
    3. 不能使用arguments对象,可以使用rest参数代替
    4. 不可以使用yield命令,因此箭头函数不能使用Generator函数

    this指向问题

    箭头函数的this固定指向其定义时的作用域,实际原因是其没有自己的this,导致其this就是外部代码块的this,也是因此所以它也不能用作构造函数。

    因为箭头函数没有自己的this,所以它也不能使用bind,call,apply来改变this指向:

    (function(){
        return (() => this.x).bind({x:'inner'})();
    }).call({x:'outer'});
    //outer
    

    以上代码中,箭头函数没有this,bind无效,其this值仍然为外部function的this。

    绑定this

    拜读阮一峰的《ES6标准入门》,还介绍了ES7提出的“函数绑定”,使用双冒号,左边为对象,右边为函数,用来取代call,apply,bind调用:

    foo::bar;
    //等同于
    bar.bind(foo);
    

    此处不做深究。

    尾调用优化

    没看懂,略。

    相关文章

      网友评论

          本文标题:007_ES6知识点总结(04)函数的拓展

          本文链接:https://www.haomeiwen.com/subject/pqvtqhtx.html