zoukankan      html  css  js  c++  java
  • ES6学习笔记二:各种扩展

    转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7242967.html

    一:字符串扩展

    1:字符串遍历器

    for (let char of str) {
      //
    }

    这个遍历器最大的优点是可以识别大于0xFFFF的码点,传统的for循环无法识别这样的码点。

    2:确定一个字符串是否包含在另一个字符串中

    • includes():返回布尔值,表示是否找到了参数字符串。
    • startsWith():返回布尔值,表示参数字符串是否在源字符串的头部。
    • endsWith():返回布尔值,表示参数字符串是否在源字符串的尾部。

    3:字符串重复n次

    str.repeat(n) //strstrstr...重复n次

    如果repeat的参数是负数或者Infinity,会报错。

    4:字符串补全到所需长度

    padStart(n,sub)用于头部补全,padEnd(n,sub)用于尾部补全。

    用sub把字符串在头/尾补全到n长度。

    如果原字符串的长度,等于或大于指定的最小长度,则返回原字符串。

    如果省略第二个参数,默认使用空格补全长度。

    5:模版字符串

    在js代码中,可以用 反引号  定义模版字符串,模版字符串中可以使用 ${变量、调用函数、js表达式} 来插入值。

    $('#result').append(`
      There are <b>${basket.count}</b> items
       in your basket, <em>${fn()}</em>
      are on sale!
    `);

    6:标签模版

    是一种特殊的函数调用形式:模版字符串跟在一个函数名后面,“标签”指的就是函数,紧跟在后面的模板字符串就是函数的参数。

    如果模板字符里面有变量,就不是简单的调用了,而是会将模板字符串先处理成多个参数,再调用函数。

    var a = 5;
    var b = 10;
    
    tag`Hello ${ a + b } world ${ a * b }`;
    // 等同于
    tag(['Hello ', ' world ', ''], 15, 50);

    7:raw()

    String.raw方法,用来充当模板字符串的处理函数,对模版字符串中每一个斜杠都转义(即斜杠前面再加一个斜杠),然后返回替换原模板字符串。

    String.raw`Hi
    ${2+3}!`;
    // "Hi\n5!"

    如果原字符串的斜杠已经转义(即:已经有转义),那么String.raw不会做任何处理。

    二:正则的扩展

    1:正则表达式的创建:第一个参数是模式字符串,这时第二个参数表示正则表达式的修饰符(flag)。

    var regex = new RegExp('xyz', 'i');

    修饰符:
    g:全局修饰符

    u:unicode修饰符

    y修饰符,叫做“粘连”(sticky)修饰符:后一次匹配都从上一次匹配成功的下一个位置开始,y修饰符确保匹配必须从剩余的第一个位置开始,这也就是“粘连”的涵义。

    s修饰符:dotall模式,使得 . 可以匹配包括行终止符在内的一切内容。

    2:字符串对象共有4个方法,可以使用正则表达式:match()replace()search()split()

    3:返回修饰符

    新增了flags属性,会返回正则表达式的修饰符。

    /abc/ig.source
    // "abc"
    
    // 返回正则表达式的修饰符
    /abc/ig.flags
    // 'gi'

    三:Number的扩展

    1:二进制和八进制表示法:

     分别用前缀0b(或0B)和0o(或0O)跟数字 来表示二进制和八进制数据。

    0b111110111 == 503
    0o767 == 503

    如果要将0b0o前缀的字符串数值转为十进制,要使用Number方法:

    Number('0b111')  // 7

    2:检查数据是否有效、是否非数

    Number.isFinite(number)用来检查一个数值是否为有限的(finite)。

    Number.isNaN(number)用来检查一个值是否为NaN

    3:字符串数字转化为数字

    Number.parseInt('12.34') // 12
    Number.parseFloat('123.45#') // 123.45

    4:Number.isInteger()用来判断一个值是否为整数。

    5:极小值

    新增一个极小的常量Number.EPSILON

    引入一个这么小的量的目的,在于为浮点数计算,设置一个误差范围,如果这个误差能够小于Number.EPSILON,我们就可以认为得到了正确结果。

     6:整数范围

    JavaScript能够准确表示的整数范围在-2^532^53之间(不含两个端点)。

    ES6引入了Number.MAX_SAFE_INTEGERNumber.MIN_SAFE_INTEGER这两个常量,用来表示这个范围的上下限。

    Number.isSafeInteger(number)则是用来判断一个整数是否落在这个范围之内。

    7:Math新增方法

    Math对象上新增了17个与数学相关的方法。所有这些方法都是静态方法,只能在Math对象上调用。

    1)取小数的整数部分

    Math.trunc方法用于去除一个数的小数部分,返回整数部分。

    2)判断正负

    Math.sign方法用来判断一个数到底是正数、负数、还是零。

    它会返回五种值。

    • 参数为正数,返回+1;
    • 参数为负数,返回-1;
    • 参数为0,返回0;
    • 参数为-0,返回-0;
    • 其他值,返回NaN。

    3)立方根

    Math.cbrt方法用于计算一个数的立方根。

    4)求参数平方和的平方根

    Math.hypot()方法返回所有参数的平方和的平方根。

    5)Math.log10(x)返回以10为底的x的对数。如果x小于0,则返回NaN。

    6)Math.log2(x)返回以2为底的x的对数。如果x小于0,则返回NaN。

    7)6个双曲函数方法。

    • Math.sinh(x) 返回x的双曲正弦(hyperbolic sine)
    • Math.cosh(x) 返回x的双曲余弦(hyperbolic cosine)
    • Math.tanh(x) 返回x的双曲正切(hyperbolic tangent)
    • Math.asinh(x) 返回x的反双曲正弦(inverse hyperbolic sine)
    • Math.acosh(x) 返回x的反双曲余弦(inverse hyperbolic cosine)
    • Math.atanh(x) 返回x的反双曲正切(inverse hyperbolic tangent)

    8)指数运算符(**):a**b=a的b次幂

    四:函数扩展

    1)函数在定义时,可以为参数指定默认值(同python一样,默认值参数要放在参数列表后面部分)

    2)调用函数时,可以通过解构赋值来传参

    3)多余参数:

    ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数。

    rest 参数搭配的变量是一个数组,该变量将多余的参数放入数组中。

    function add(...values) {
      let sum = 0;
    
      for (var val of values) {
        sum += val;
      }
    
      return sum;
    }

    rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错。

    4)箭头函数:参数=>函数体

    简单的箭头函数:var f=(参数)=>返回值

    var sum = (num1, num2) => num1 + num2;

    复杂的箭头函数:函数体多于一个语句,则用{}括起来,用return返回结果

    var sum = (num1, num2) => { ......;return num1 + num2; }

    箭头函数使得表达更加简洁

    5)尾调用优化

    尾调用(Tail Call)是函数式编程的一个重要概念,指某个函数的最后一步是调用另一个函数。【最后一步不等于最后一条语句,而是在return语句的最末尾处】

    尾调用由于是函数的最后一步操作,所以不需要保留外层函数的调用帧,因为调用位置、内部变量等信息都不会再用到了,所以可以删除外部函数调用帧,只保留内层尾调用的函数帧即可。

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

    6)尾递归:优化递归溢出的方法

    函数调用自身,称为递归。如果尾调用自身,就称为尾递归。

    递归非常耗费内存,因为需要同时保存成千上百个调用帧,很容易发生“栈溢出”错误(stack overflow)。但对于尾递归来说,由于只存在一个调用帧,所以永远不会发生“栈溢出”错误。

    尾递归的实现,往往需要改写递归函数,确保最后一步只调用自身。做到这一点的方法,就是把所有用到的内部变量改写成函数的参数。 

    函数式编程有一个概念,叫做柯里化(currying),意思是将多参数的函数转换成单参数的形式:

    function currying(fn, n) {//定义currying函数:在函数内部调用参数函数
      return function (m) {
        return fn.call(this, m, n);
      };
    }
    
    function tailFactorial(n, total) {
      if (n === 1) return total;
      return tailFactorial(n - 1, n * total);
    }
    
    const factorial = currying(tailFactorial, 1);

    7)尾递归优化:把递归转化为循环

    function tco(f) {
      var value;
      var active = false;
      var accumulated = [];
    
      return function accumulator() {
        accumulated.push(arguments);
        if (!active) {
          active = true;
          while (accumulated.length) {
            value = f.apply(this, accumulated.shift());
          }
          active = false;
          return value;
        }
      };
    }
    
    var sum = tco(function(x, y) {
      if (y > 0) {
        return sum(x + 1, y - 1)
      }
      else {
        return x
      }
    });
    
    sum(1, 100000)

    tco函数是尾递归优化的实现,奥妙就在于状态变量active。默认情况下,这个变量是不激活的。一旦进入尾递归优化的过程,这个变量就激活了。然后,每一轮递归sum返回的都是undefined,所以就避免了递归执行;而accumulated数组存放每一轮sum执行的参数,总是有值的,这就保证了accumulator函数内部的while循环总是会执行。这样就很巧妙地将“递归”改成了“循环”,而后一轮的参数会取代前一轮的参数,保证了调用栈只有一层

    五:数组扩展

    1)扩展运算符

     扩展运算符(spread)是三个点(...)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列

    function push(array, ...items) {
      array.push(...items);
    }
    function f(x, y, z) {
      // ...
    }
    var args = [0, 1, 2];
    f(...args);

    扩展运算符的应用:

    合并数组:

    // ES6的合并数组
    var combine=[...arr1, ...arr2, ...arr3]

    把字符串转化为字符数组:

    [...'hello']
    // [ "h", "e", "l", "l", "o" ]

    拆分任何可迭代对象成为数组:

    let arr = [...可迭代对象];

    2)将对象转为数组

    Array.from方法用于将两类对象转为真正的数组:类似数组的对象(array-like object)和可遍历(iterable)的对象(包括ES6新增的数据结构Set和Map)。

    let arrayLike = {
        '0': 'a',
        '1': 'b',
        '2': 'c',
        length: 3
    };
    
    let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']

    常见的类似数组的对象是DOM操作返回的NodeList集合,以及函数内部的arguments对象Array.from都可以将它们转为真正的数组。

    Array.from还可以接受第二个参数(处理函数),作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组

    Array.from(arrayLike, x => x * x);

    3)将一组离散值转化为数组

    Array.of方法用于将一组值,转换为数组。

    Array.of(3, 11, 8)

    4)数组对象的内部复制

    copyWithin方法,在当前数组内部,将指定位置的成员复制到其他位置(会覆盖原有成员),然后返回当前数组。也就是说,使用这个方法,会修改当前数组。

    Array.prototype.copyWithin(target, start = , end = )

    它接受三个参数:

    • target(必需):从该位置开始替换数据。
    • start(可选):从该位置开始读取数据,默认为0。如果为负值,表示倒数。
    • end(可选):到该位置前停止读取数据,默认等于数组长度。如果为负值,表示倒数。
    // 将3号位复制到0号位
    [1, 2, 3, 4, 5].copyWithin(0, 3, 4)
    // [4, 2, 3, 4, 5]

    5)数组查找方法

    find方法:用于找出第一个符合条件的数组成员。它的参数是一个回调函数,所有数组成员依次执行该回调函数,直到找出第一个回调函数返回值为true的成员,然后返回该成员。如果没有符合条件的成员,则返回undefined

    [1, 4, -5, 10].find((n) => n < 0)

    findIndex方法的用法与find方法非常类似,返回第一个符合条件的数组成员的位置,如果所有成员都不符合条件,则返回-1

    [1, 5, 10, 15].findIndex(function(value, index, arr) {
      return value > 9;
    }) // 2

    6)数组填充

    fill方法使用给定值,填充(覆盖)一个数组。【相当于memset】

    ['a', 'b', 'c'].fill(7)
    // [7, 7, 7]

    fill方法还可以接受第二个和第三个参数,用于指定填充的起始位置和结束位置

    ['a', 'b', 'c'].fill(7, 1, 2)
    // ['a', 7, 'c']

    7)数组遍历

    entries()keys()values():返回一个遍历器对象,可以用for...of循环进行遍历:

    keys()是对键名(下标)的遍历、values()是对键值的遍历,entries()是对键值对的遍历。

    for (let index of ['a', 'b'].keys()) {
      console.log(index);
    }
    // 0
    // 1
    
    for (let elem of ['a', 'b'].values()) {
      console.log(elem);
    }
    // 'a'
    // 'b'
    
    for (let [index, elem] of ['a', 'b'].entries()) {
      console.log(index, elem);
    }
    // 0 "a"
    // 1 "b"

    8)是否包含

    includes方法返回一个布尔值,表示某个数组是否包含给定的值:

    [1, 2, 3].includes(2)

    第二个参数表示搜索的起始位置,默认为0。如果第二个参数为负数,则表示倒数的位置:

    [1, 2, 3].includes(3, -1); // true

    六:对象扩展

     1)属性简写

    ES6允许在对象之中,把外面定义的变量作为自己的属性:属性名为变量名, 属性值为变量的值。

    var foo = 'bar';//定义变量
    var baz = {foo};//把变量作为对象属性

    2)方法简写

    对象内定义方法,可以不加function前缀:

    var o = {
      method() {
        return "Hello!";
      }
    };
    // 等同于
    var o = {
      method: function() {
        return "Hello!";
      }
    };

    3)属性的getter和setter:用get、set声明函数

    const obj = {
      get foo() {},
      set foo(x) {}
    };

    4)对象的值相等比较

    ES6提出“Same-value equality”(同值相等)算法,Object.is就是部署这个算法的新方法。它用来比较两个值是否严格相等,与严格比较运算符(===)的行为基本一致。

    Object.is(obj1, obj2)

    5)对象合并

    Object.assign方法用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。

    第一个参数是目标对象,后面的参数都是源对象:

    var target = { a: 1, b: 1 };
    
    var source1 = { b: 2, c: 2 };
    var source2 = { c: 3 };
    
    Object.assign(target, source1, source2);
    target // {a:1, b:2, c:3}

    如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。

    Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用,这个对象的任何变化,都会反映到目标对象上面。

     6)对象属性的遍历

    ES6 一共有5种方法可以遍历对象的属性。
    
    (1)for...in
    
    for...in循环遍历对象自身的和继承的可枚举属性(不含 Symbol 属性)。
    
    (2)Object.keys(obj)
    
    Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含 Symbol 属性)。
    
    (3)Object.getOwnPropertyNames(obj)
    
    Object.getOwnPropertyNames返回一个数组,包含对象自身的所有属性(不含 Symbol 属性,但是包括不可枚举属性)。
    
    (4)Object.getOwnPropertySymbols(obj)
    
    Object.getOwnPropertySymbols返回一个数组,包含对象自身的所有 Symbol 属性。
    
    (5)Reflect.ownKeys(obj)
    
    Reflect.ownKeys返回一个数组,包含对象自身的所有属性,不管属性名是 Symbol 或字符串,也不管是否可枚举。

    7)Object.keys(),Object.values(),Object.entries()

    Object.keys方法:返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名。

    Object.values方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值。

    Object.entries方法返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键值对数组。

    8)对象的扩展运算符
    扩展运算符  ...  不仅可以作用于数组,也可以作用于对象。

    对象的解构赋值:用于从一个对象取值,相当于将所有可遍历的、但尚未被读取的属性,分配到指定的对象上面。

    let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
  • 相关阅读:
    Coursera 机器学习笔记(八)
    Coursera 机器学习笔记(七)
    Coursera 机器学习笔记(六)
    Coursera 机器学习笔记(五)
    Coursera 机器学习笔记(四)
    埃拉托斯特尼筛法
    Floyd判圈算法
    多数投票算法
    Coursera 机器学习笔记(三)
    Coursera 机器学习笔记(二)
  • 原文地址:https://www.cnblogs.com/ygj0930/p/7242967.html
Copyright © 2011-2022 走看看