美文网首页
2. 函数的扩展

2. 函数的扩展

作者: wudimingwo | 来源:发表于2018-12-05 14:24 被阅读0次

    返回指定长度的随机字符串

          function Random (n) {
            let max = 1;
            for(let i = 0; i < n; i++) {
              max *= 10;
            }
            
            return function () {
                let str = '' + parseInt(Math.random() * max);
    
                    下面这小段我就看不懂什么意思了
                    count不是必然= 0 嘛?
                    补0操作有可能执行嘛?
    
                    明白了, 是有可能执行的, 因为 Math.random() 返回的是0-1之间的数
                    也就是可以返回0.001,所以有可能出现count> 0的情况
                let count = n - str.length;
                for(let i = 0; i < count; i++) {
                  str += '0';
                }
                return str
            }
          }
          
          let random8 = Random(8);
          
          console.log(random8());
    

    函数的默认值

    第一种

          function fn (name) {
            var name = name || 'none';
          }
    有缺陷 '',0,null,false 等值时达不到预期
    

    第二种

          function fn (name) {
            var name = name === undefined ?  'none' : name;
          }
    

    es6

          function fn (name = 'none') {
            // 绝对== undefined 时 才会走默认值
          }
    babel 翻译
    function fn() {
      var name = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'none';
    }
    

    情形1

          function Person (name, age = 18, weight) {
            this.name = name;
            this.age = age;
             this.weight = weight;
            
          }
          new Person('dd',undefined,63);
          想要触发默认值 必须要占位,而不能
          new Person('dd',,63);      
    

    情形2 arguments 的表现

    1. 默认情况
          function num (num1) {
              console.log(num1, arguments[0]);//1,1
              num1 = 3;
              console.log(num1, arguments[0]);//3,3
              arguments[0] = 4;
              console.log(num1, arguments[0]);//4,4
          }
          num(1);
    
    默认情况下 arguments[0] 和 num1 互相绑定
    
    1. 严格模式
          function num (num1) {
              "use strict"
              console.log(num1, arguments[0]);//1,1
              num1 = 3;
              console.log(num1, arguments[0]);//3,1
              arguments[0] = 4;
              console.log(num1, arguments[0]);//3,4
          }
          num(1);
    除了刚传入时保持一致, 互相并不绑定
    
    1. 设置默认值将触发严格模式
          function num (num1 = 0) {
              console.log(num1, arguments[0]);//1,1
              num1 = 3;
              console.log(num1, arguments[0]);//3,1
              arguments[0] = 4;
              console.log(num1, arguments[0]);//3,4
          }
          num(1);
    

    默认值可以是变量

          let obj2 = {};
          obj2.num = 18;
          function num (obj = obj2) {
              console.log(obj.num);// 18
          }
          num();
    
    // 也就是说, 从某种角度来讲, 可以传两次参数?
    // 第二次不传, 就默认用第一次传的参数?
    

    惰性求值?

          function getValue () {
            console.log('hello');
            return 6;
          }
          function add (m,n = getValue()) {
            return n + m;
          }
          console.log(add(1,1));
          console.log(add(1));
    
    触发默认值时, 才会执行该函数. 有点类似回调?
    

    TDZ 暂时性死区
    下面代码执行会报错嘛?
    不会

          function add (m,n = m) {
            return n + m;
          }
          console.log(add(1,1));//2,2
          console.log(add(1));//2,2
    
    相当于
    let m = 1;
    let n = m;
    

    下面代码执行会报错嘛?

          function add (m =n ,n) {
            return n + m;
          }
          console.log(add(1,1));//2,2
          console.log(add(undefined,1));// 报错
    相当于 
    let m = n;
    let n = 1;
    

    无命名参数和扩展运算符
    参数不定时, 需要用arguments 来访问
    箭头函数不支持arguments

    作为形参使用,生成数组

          function add(arr, ...arg) {
            console.log(arg);
            console.log(arguments);
            for(let i = 0; i < arg.length; i++) {
              arr[i] = arg[i] + 1;
            }
            
            return arg;
          }
          let arr = [];
          add(arr,1,2,3,4);
          console.log(arr);//[2,3,4,5]
    
    babel 翻译
    function add(arr) {
      for (var _len = arguments.length, arg = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        arg[_key - 1] = arguments[_key];
      }
    
      console.log(arg);
      console.log(arguments);
      for (var i = 0; i < arg.length; i++) {
        arr[i] = arg[i] + 1;
      }
    
      return arg;
    }
    
    可以看到 , ...arg的处理 实际上用的是 arguments
    

    每个函数只能有一个不定参数
    下面代码是否会报错?

          function add(arr,...arg,...arg1) {
            
          }
          add([],1,2,3,4);
    

    不定参数不能有默认值
    下面代码是否会报错?

          function add(arr,...arg=[]) {
            
          }
          add([],1,2,3,4);
    

    不定参数 必须放在最后面
    下面代码是否会报错?

          function add(first,...arg,last) {
            
          }
          add(1,2,3,4);
    

    非形参使用时, 扒开数组.

    
    function add(a,b,c) {
            console.log(a + b + c);
            return a + b + c
          }
          let arr = [1,2,3];
          add(...arr);// 传参时使用
    
    bable翻译
    
    function add(a, b, c) {
            console.log(a + b + c);
            return a + b + c;
    }
    var arr = [1, 2, 3];
    add.apply(undefined, arr);
    
    看得出, 用的是apply
    

    可用于数组合并

          let arr1 = [1,2,3];
          let arr2 = [4,5,6];
          let arr3 = arr1.concat(arr2);
          
          let arr4 = [...arr1,...arr2];
          
          console.log(arr3,arr4);
    
    babel 翻译可知 用得也是concat
    

    箭头函数

    基本形式

          () => {}
    

    简写形式

          let fn = name => name;
           对于小括号, 参数必须有且只有一个时,可省略
           对于 {} , 只有一条语句时, 可省略, 并且返回语句执行后的值
    

    箭头函数中返回对象

            let returnObj = (name) => ({name})
     需要小括号包裹一下, 表明是对象.
    

    立即执行函数

            let name = (name => name)('mike');
    

    箭头函数

    1. 没有this
    2. 没有 arguments
    3. 没有super
    4. 没有prototype
      不能被 new 操作符运算
      call,apply,bind 也失去作用
            let age = "mike";
            let fn =  () => {
              console.log(this == window);/ true
              console.log(this.age);/ undefined
            }
            fn();
            console.log(fn.prototype);/ undefined
    
    babel翻译
    
    var age = "mike";
    var obj = {
      age: '18'
    };
    var fn = function fn() {
      console.log(undefined == window);
      console.log(undefined.age); // undefined
    };
    var fn1 = fn.bind(obj);
    fn1();
    
    // 可以看出, 所有this都换成了 undifend
    ---
    
    上述结论是有问题的, 之所以 this.age 会返回 undefined 
    是因为 用let生命的变量, 无法用window 来访问.
    该用var声明时,会返回mike
    
    

    this 绑定分为四种 (权重依次递增)

    1. 默认绑定(this 指向window)
    2. 隐式绑定 ( this 指向 调用函数的对象)
    3. 显示绑定 ( this 指向 call, apply, bind 绑定的对象)
    4. new 绑定 ( this 指向 实例)

    箭头函数中没有this
    箭头函数中 this指向,离自己最近的非箭头函数作用域中的this
    (非箭头函数作用域是有this的, 而块级作用域{}是没有this的?)

    下面代码输出结果是什么?

          var age = "peter";
          let obj = {
            age: 'mike',
            print: function() {
              let show = () => { console.log(this.age) };
              show();
            }
          }
          obj.print();// mike
    

    应用, setTimeout

          var name = "mike";
          function show () {
            setTimeout(() => {
              console.log(this.name);
            },1000);
          }
          show();// mike
          show.call({name : "peter"});// peter
    

    arguments与此类似,指向非箭头函数的arguments
    这对使用setTimeout 就很友好感觉.

          function show () {
            setTimeout(() => {
              console.log(arguments);//[1,2,3]
              console.log(arguments[0]);// 1
            },1000);
          }
          show(1,2,3);//
    

    阮一峰的es6, 函数扩展

    相关文章

      网友评论

          本文标题:2. 函数的扩展

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