2. 函数的扩展

2018-12-05  本文已影响0人  wudimingwo

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

      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, 函数扩展

上一篇 下一篇

猜你喜欢

热点阅读