美文网首页
函数的扩展

函数的扩展

作者: 阿龙哟 | 来源:发表于2018-11-19 18:22 被阅读0次

    1.函数参数的默认值

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


    image.png
    注意:

    (1)参数变量是默认声明的,不能用let和const再次声明
    (2)默认参数值不是单纯的传值的而是惰性求值的

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

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

    因为函数没有提供默认值,当调用函数时参数为空或者不为对象类型时就会报错,这里只是用了对象的解构赋值的默认值

    function foo({x,y=5} = {}) 
    {
      console.log(x,y)
    }
    foo()  // undefined 5
    
    

    参数默认值的位置

    参数默认值一般应该是尾参数,如果不是尾参数,一般是无法省略的,需要显式输入undefined ,输入undefined可以触发默认值,输入null则没有这个效果

    函数的length属性

    length属性的含义是,该函数预期传入的参数个数。函数指定了默认值后,预传入的参数个数就不包括这个参数了。rest参数也不会计入length属性
    另外如果默认值不是尾参数,那么length属性将不会再计算默认值后面的参数了

    作用域

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


    二、rest参数

    ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用arguments对象了。
    res参数后面不能再有其他参数了
    length属性,不包括rest参数


    三、严格模式

    es6只要函数参数使用了默认值、解构赋值、或者扩展运算符,函数内部就不能显示设定为严格模式
    因为只能在函数体中设置严格模式,然而参数却是优先于函数体执行的,所以就矛盾了


    四、name属性

    函数的name属性,返回该函数的函数名。

    var f = function(){}//后面是匿名函数
    

    es5 name会返'回'
    es6 name会返回‘f’


    五、箭头函数

    注意

    1.箭头函数直接返回一个对象,必须要在对象外面加一个括号
    2.箭头函数可以和变量解构结合使用


    箭头函数有几个使用注意点。

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

    function foo(){
        setTimeout(()=>{
            console.log(this.id)
        },100)
    }
    
    function fbb(){
        setTimeout(function(){
            console.log(this.id)
        },100)
    }
    
    var id = 21 
    
    foo.call({id:42}) ///42
    fbb.call({id:42}) /// 21
    
    

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

    (3)不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数代替。

    (4)不可以使用yield命令,因此箭头函数不能用作 Generator 函数。

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


    六、双冒号运算符
    函数绑定运算符是并排的两个冒号(::),双冒号左边是一个对象,右边是一个函数。该运算符会自动将左边的对象,作为上下文环境(即this对象),绑定到右边的函数上面。


    七、尾调用优化
    尾调用(Tail Call)是函数式编程的一个重要概念,本身非常简单,一句话就能说清楚,就是指某个函数的最后一步是调用另一个函数。

    尾调用不一定出现在函数尾部,只要是最后一步操作即可。

    function f() {
      let m = 1;
      let n = 2;
      return g(m + n);
    }
    f();
    
    // 等同于
    function f() {
      return g(3);
    }
    f();
    
    // 等同于
    g(3);
    

    上面代码中,如果函数g不是尾调用,函数f就需要保存内部变量m和n的值、g的调用位置等信息。但由于调用g之后,函数f就结束了,所以执行到最后一步,完全可以删除f(x)的调用帧,只保留g(3)的调用帧。

    这就叫做“尾调用优化”(Tail call optimization),即只保留内层函数的调用帧。如果所有函数都是尾调用,那么完全可以做到每次执行时,调用帧只有一项,这将大大节省内存。这就是“尾调用优化”的意义。


    八、尾逗号

    因此新的语法允许定义和调用时,尾部直接有一个逗号。

    相关文章

      网友评论

          本文标题:函数的扩展

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