美文网首页
ES6 函数的扩展

ES6 函数的扩展

作者: 灬劣徒 | 来源:发表于2019-03-13 15:27 被阅读0次
    image.png

    函数参数的默认值

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

    function log(x,y = 'world') {
      console.log(x,y)      
    }   
    log('hello')  //'hello'                  
    
    //参数变量是 默认声明的,所以不能用let或const 再次声明
    function foo(x = 5) {
      let x = 1;
      const x = 2;  
    }
    
    //函数参数默认值是惰性求值的
    let x = 100;
    function foo(p = x + 1){
      console.log(p) 
    }
    foo(); //101
    x = 101;
    foo() //102
    

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

    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() //TypeError:cannot read property 'x' of undefined;
    

    以上代码只使用对象的解构赋值的默认值,并没有使用函数参数的默认值,下面是结合使用的列子:

    function foo({x,y = 5} = {}) {
      console.log(x,y) //undefined,5
    }
    
    //不设置函数参数默认值,会报错
    function fetch(url,{body:'',method:'GET',headers = {} } ) {
      console.log(method)
    }
    fetch('http:example.com') //报错
    
    //设置参数默认值,不会报错
    function(url,{body:'',method:'GET',headers = {} } = {} ) {
      console.log(method)
    }
    fetch('http:example')  //GET
    

    老铁,''是时候表演真正的技术了'',说说以下两种写法的区别,顺便再做几个练习题吧

    //写法一:设置了对象解构赋值的默认值,但是函数参数的默认值是个空对象
    function m1({x = 0,y = 0} = {}) {
      return [x,y] //
    }
    
    //写法二:设置了函数参数的默认值是一个有属性的对象,但是没有设置对象解构赋值的默认值
    function m2({x,y} = {x:0,y:0}) {
      return [x,y]
    }
    注意:({x,y} = {x:0,y:0}) 不能写成({x,y} = {x= 0,y = 0})
    
    m1(); // [0,0]
    m2(); // [0,0]
    m1({}); //[0,0]
    m2({}); //[undefined,undefined]
    m1({x:3,y:8}); //[3,8]
    m2{{x:3,y:8}}; //[3,8]
    m1({x:3}) //[3,0]
    m2({x:3}) //[3,undefined]
    m1({z:3}); //[0,0]
    m2({z:3}); //[undefined.undefined]
    

    参数默认值的位置

    通常定义默认值的参数,都会在参数值的尾部(就这样吧~稍作了解就得了)

    function foo(x,y = 5,z) {
      return [x,y,z]
    }
    foo(); //[undefined,5,undefined]
    foo(1); //[1,5,undefined]
    foo(1, ,2); // 报错
    foo(1,undefined,2) //[1,5,2]
    foo(1,null,2) //[1,null,2]
    

    函数的length属性(该函数预期传入的参数个数,如果设置默认值,就不包括在这个里面了)

    函数参数设置默认值以后,函数的length属性,返回没有设置默认值的参数个数

    (function f1(x){}).length  // 1
    (function f2(x = 1){}).length // 0
    (function f3(x,y,z = 5){}).length // 2
    (function f4(x,y = 1,z){}).length // 1
    (function f5(x =1,y,z){}).length // 0
    (function f6(...args){}).length // 0
    

    作用域(感觉这章很重要,但是有点看不懂啊)

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


    rest参数

    ES6引入rest参数,用来获取函数的多余参数(...变量名).这样就不用arguments

    //rest参数代替arguments对象
    function args(){                                                                     
      return Array.prototype.slice.call(arguments).sort();     =>     const args = (...numbers) => numbers.sort();                      
    }                                                                                      
    
    function push(array,...items) {
      items.forEach(function(item) {
        array.push(item);
        console.log(item)
      })
    }
    var a  = [];
    push(a,1,2,3);
    
    

    请注意两个坑: ① rest参数只能在参数的最后 ②函数的length属性不包括rest参数

    严格模式

    ES5可以在函数内部使用严格模式'user strict'
    ES6做出了一点修改,即只要函数参数使用了默认值,解构赋值,或者扩展运算符(rest参数),函数内部就不能显示设定为严格模式

    name属性(函数的name属性,返回该函数的函数名)

    在ES5,如果一个匿名函数赋值给一个变量,这个函数的name属性返回的是一个空字符串
    在ES6,会返回实际的函数名

    const foo = function baz(){}
    //ES5
    foo.name // baz
    //ES6
    foo.name // baz
    
    //Function的实例对象是anonymous
    (new Function).name // anonymous
    
    //bind返回的函数,name属性值会加上bound前缀
    function foo() {}
    foo.bind({}).name // bound foo
    (function() {}).bind({}).name // bound
    

    箭头函数(来了,传说中的箭头函数~)

    //如果箭头函数没有参数or需要多个参数,就使用一个圆括号代表参数部分
    //如果只有一个参数,可以省略圆括号
    let f = () => { 5 }
    let sum = (num1,num2) => {return num1 + num2 }
    let temp = id => console.log(id)
    
    //如果函数体中的语句多于一条,就得使用大括号(return关键词单独算是一条语句)
    let sum = (num1,num2) => { return num1 + num2}; 
    
    //如果函数体**直接**返回一个对象,必须用圆括号包裹这个对象,因为大括号被解读为一个代码块
    let getObj = id => {id:id,name:'JC_cooper'} // 报错
    let getObj = id => ({id:id,name:'JC_cooper'})
    
    • 箭头函数有4个注意点:
      1.函数中的this,就是定义时所在的对象,而不是使用时所在的对象,说白了就是,this从"动态"变成"静态"
      2.箭头函数不能用作构造函数,也就是说不能使用new命令,否则会报错
      3.不能使用arguments对象,请使用rest参数代替
      4.不可以使用yield命令,因此不可以使用Generator函数

    相关文章

      网友评论

          本文标题:ES6 函数的扩展

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