美文网首页
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. 函数的扩展

    返回指定长度的随机字符串 函数的默认值 第一种 第二种 es6 情形1 情形2 arguments 的表现 默认情...

  • 扩展函数

    1.扩展函数所属的类,必须是static类 2.扩展函数本身必须是static函数 3.扩展函数第一个参数的类型,...

  • Swift学习_扩展和协议

    1.扩展 扩展用于为已存在的类、结构体或枚举等类型添加新的功能 1.扩展计算型属性 2.扩展构造函数 扩展构造函数...

  • 从Java到Kotlin(六)

    扩展与委托 目录 1.扩展 1.1 扩展函数 1.2 扩展属性 1.3 扩展伴生对象 1.4 扩展的作用域 2.委...

  • ES6 字符串、数组、函数、对象

    字符串 1. 多行字符串 2. 字符串模板 数组 1. 扩展 2. 函数参数的扩展 3. 类数组对象转数组 函数 ...

  • Kotlin学习(三)函数

    Kotlin函数 1.函数声明 kotlin中的函数用fun声明 2.中缀符号 满足以下条件(成员函数或者扩展函数...

  • 每天学一点 Kotlin -- 类的进阶:扩展

    1. 扩展 1.1 类的扩展是给类增加新的方法或属性。 2. 扩展类的方法 1.2 扩展的语法:和定义函数差不多,...

  • 10.Kotlin扩展作用域分析与扩展的根本作用解析

    1.扩展属性 与函数类似,Kotlin支持扩展属性。 示例代码 运行结果 2.伴生对象扩展 示例代码 运行结果 3...

  • Kotlin 笔记 扩展

    扩展(extension)是指向已有的类中添加函数 扩展函数 定义扩展函数时,在函数前面加上要扩展类的名字,以下代...

  • 重拾Kotlin(12)-扩展函数和扩展属性

    一、扩展函数和扩展属性 1.1、扩展函数 扩展函数用于为一个类增加一种新的行为,这是为缺少有用函数的类进行扩展的途...

网友评论

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

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