zoukankan      html  css  js  c++  java
  • ES6入门之函数的扩展

    函数js原有的:

    属性:arguments[]、caller(调用该函数的引用,注意与callee分别开,callee指的是调用函数本身经常在递归中出现)、length(形参个数)、prototype

    方法:apply()、call()、bind()、toString()

    函数的扩展:

    • 函数参数的默认值 

        在es6之前不能给函数的参数给定默认值,一般会采用这样的方法:

    function a(x,y){
        if(typeof y === 'undefined'){
             y = 'world';
        }  
        console.log(x,y);
    }    

                es6允许设置默认值,在解构的时候使用模式匹配

        

    function log(x, y = 'World') {
      console.log(x, y);
    }
    
    log('Hello') // Hello World
    log('Hello', 'China') // Hello China
    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() // TypeError: Cannot read property 'x' of undefined
    // 写法一:设置了参数对象的解构默认值,但是对象默认为空对象
    function m1({x = 0, y = 0} = {}) {
      return [x, y];
    }
    
    // 写法二:设置了参数对象默认是一个不为空的对象
    function m2({x, y} = { x: 0, y: 0 }) {
      return [x, y];
    }
    
    m1()   //[0,0]
    m2()   //[0,0]
    m1({x:1})   //[1,0]
    m2({x:1})   //[1,undefined]

    如果设定了默认参数不在arguments的尾部则在引用函数的时候不能省略,可以用undefined代替

    这时函数的length就不是全部的arguments的长度了,而是没有设定默认值的长度

    函数作用域:一般而言函数作用域大于全局作用域,但是如果函数的参数为另一函数,则这个另一函数的作用域还是全局作用域

    • rest参数(...变量名)<=> arguments 用于获取函数多余的参数

    rest是一个数组,arguments是一个类数组(对象)

    rest只能是最后一个参数,length属性不包括rest参数

    • 扩展运算符(...)将一个数组转为用逗号分隔的参数序列

    console.log(1, ...[2, 3, 4], 5)         // 1 2 3 4 5

    可以代替apply方法,将数组转为参数

    代替concat <=> [1,2,...[]]

    生成数组:[a,...rest] = [1,2,3,4,5]; a= 1;rest = [2,3,4,5];

    可以返回多个值,正常函数只能返回数组和对象,但是扩展运算符可以将数组转化

    可以将字符串转为数组:[...'he'] = ['h','e'];

    • name:返回函数名,若为匿名函数则es5返回空字符串,es6返回赋给引用它的变量

    构造函数返回函数实例

    bind函数返回'bound'+name

    • 箭头函数‘=>’

    var f = v => v;
    等价于
    var f = function(v) {
      return v;
    };
    不需要参数或多个则:用()表示
    执行部分不只有返回值,用{},但是如果返回值为对象则需要在外部加()
    
    // 正常函数写法
    [1,2,3].map(function (x) {
      return x * x;
    });
    
    // 箭头函数写法
    [1,2,3].map(x => x * x);

    使用箭头注意点:

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

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

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

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

    没有参数的时候就调用外部函数的,同时这时的this也是外部的

    • 函数绑定'::'左边对象右边函数 <=>bind

    foo::bar;    // 等同于    bar.bind(foo);
    • 尾调用优化

    尾调用:某函数最后一步调用另一函数不一定要出现在函数尾部

    调用帧:函数调用会在内存形成一个“调用记录”,保存调用位置和内部变量等信息

    调用栈:如果在函数A的内部调用函数B,那么在A的调用帧上方,还会形成一个B的调用帧。等到B运行结束,将结果返回到A,B的调用帧才会消失。如果函数B内部还调用函数C,那就还有一个C的调用帧,以此类推。所有的调用帧,就形成一个“调用栈”(call stack)。

    尾调用优化:只保留内层函数的调用帧,节省内存

    注意,只有不再用到外层函数的内部变量,内层函数的调用帧才会取代外层函数的调用帧,否则就无法进行“尾调用优化”。

    如下代码进行尾调用优化
    function f() {
      let m = 1;
      let n = 2;
      return g(m + n);
    }
    f();
    
    // 等同于
    function f() {
      return g(3);
    }
    f();
    
    // 等同于
    g(3);
    
    如下代码则不会
    function addOne(a){
      var one = 1;
      function inner(b){
        return b + one;
      }
      return inner(a);
    }

    尾递归:尾调用自身,不会发生栈溢出

    递归非常耗内存,需要同时保存多个调用帧,解决方法:

    法一: 确保最后一步只调用自己,把所有用到的内部变量改写成函数的参数

    function tailFactorial(n, total) {
      if (n === 1) return total;
      return tailFactorial(n - 1, n * total);
    }
    
    function factorial(n) {
      return tailFactorial(n, 1);
    }
    
    factorial(5) // 120

    法二:采用ES6的函数默认值

    function factorial(n, total = 1) {
      if (n === 1) return total;
      return factorial(n - 1, n * total);
    }
    
    factorial(5) // 120

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

    因为在正常模式下,函数内部有两个变量,可以跟踪函数的调用栈。

    • func.arguments:返回调用时函数的参数。
    • func.caller:返回调用当前函数的那个函数。
    function restricted() {
      "use strict";
      restricted.caller;    // 报错
      restricted.arguments; // 报错
    }
    restricted();
    • 函数内部的最后一个参数可以有尾逗号

  • 相关阅读:
    StrUtils
    WebUtil
    TreeUtil
    SQL解决表结构不同的数据同步方案
    MongoDB还原备份Bson文件及导出SQL文件
    Tengine安装步骤
    C++_练习—多态_virtual
    C++_练习—this指针
    C++_练习—继承_构造初始化列表
    C++_练习—继承_构造析构
  • 原文地址:https://www.cnblogs.com/sker/p/5457797.html
Copyright © 2011-2022 走看看