• ES6中的新特性


    本人最近学习es6一些方法,难免有些手痒,想着能不能将这些方法总结下,如下

    1、数组的扩展

    1)首先什么是伪数组

    无法直接调用数组方法或期望length属性有什么特殊的行为,但仍可以对真正数组遍历方法来遍历它们,例如:函数的argument参数,调用getElementsByTagName,document.childNodes等等

    2、函数扩展

    document.querySelectorAll('元素') 相当于 document.getElementsByTagName('元素') 一样 

    合并数组

    // ES5
    [1, 2].concat(more)
    // ES6
    [1, 2, ...more]
    
    var arr1 = ['a', 'b'];
    var arr2 = ['c'];
    var arr3 = ['d', 'e'];
    
    // ES5的合并数组
    arr1.concat(arr2, arr3);
    // [ 'a', 'b', 'c', 'd', 'e' ]
    
    // ES6的合并数组
    [...arr1, ...arr2, ...arr3]
    // [ 'a', 'b', 'c', 'd', 'e' ]
    

     字符串

    es6默认都是属于严格模式下,“...”为扩展运算符

    let str = 'xuD83DuDE80y';
    str.split('').reverse().join('')
    // 'yuDE80uD83Dx'
    [...str].reverse().join('')
    // 'yuD83DuDE80x'

    name属性

    函数的name属性,返回该函数的函数名。

    function fn() {}
    fn.name // "fn"
    

    箭头函数

    // 嵌套的箭头函数
    function insert(value) { return {into: function (array) { return {after: function (afterValue) { array.splice(array.indexOf(afterValue) + 1, 0, value); return array; }}; }}; } insert(2).into([1, 3]).after(1); //[1, 2, 3] // 使用箭头函数 let insert = (value) => ({into: (array) => ({after: (afterValue) => { array.splice(array.indexOf(afterValue) + 1, 0, value); return array; }})}); insert(2).into([1, 3]).after(1); //[1, 2, 3]

    现在问题来了,什么是链式调用?

    解答:其实,上面的代码可以说是一种链式调用,使用面向对象写,里面写几个方法,就像如下代码一样,jquery中ajax使用promise一样,将异步用同步流程表达出来。

    var Lianshi = function(){ }
    Lianshi.prototype = {
           css:function(){
                 console.log("设置css样式");
                  return this;  
           },
           show:function(){
                   console.log("将元素显示");
                   return this;
           },
           hide:function(){
                  console.log("将元素隐藏");
           }
      };
    var lianshi = new Lianshi();
    lianshi.css().css().show().hide();

    箭头函数注意的四点:

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

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

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

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

     绑定this

    箭头函数可以绑定this,显示绑定this的写法(call、apply、bing),call、apply的作用就是能够改变this的指向

    递归函数

    // 斐波拉切数列 也是递归的一种  传的值过大,容易造成堆栈溢出 内存泄漏
    function Fibonacci (n) {
      if ( n <= 1 ) {return 1};
      return Fibonacci(n - 1) + Fibonacci(n - 2);
    }
    
    Fibonacci(10); // 89
    // 尾调递归  
    function
    factorial(n, total = 1) { if (n === 1) return total; return factorial(n - 1, n * total); } factorial(5) // 120

    只要在严格模式下,才能使尾调递归函数优化,(由于递归就是使用栈太多,造成溢出,想要优化,就只能减少栈的使用,故使用循环来进行递归)

    额外说点:造成内存泄漏的原因:1)使用了递归; 2)使用了小数点,如:0.0000000001;3)setTimeout第一个参数是字符串

    // 优化尾调递归函数
    function trampoline(f) {
      while (f && f instanceof Function) {
        f = f();
      }
      return f;
    }
    function sum(x, y) {
      if (y > 0) {
        return sum.bind(null, x + 1, y - 1);
      } else {
        return x;
      }
    }
    trampoline(sum(1, 100000))
    // 100001
    // 使用蹦床函数也可以优化尾调函数
    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)
    // 100001

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

    额外说点:

    继承:原型继承、原型链继承、call/apply继承

    ES6 模块之中,顶层的this指向undefined,即不应该在顶层代码使用this

    import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构。

    require是运行时加载模块,import命令无法取代require的动态加载功能。

    importexport命令只能在模块的顶层,不能在代码块之中(比如,在if代码块之中,或在函数之中)。

  • 相关阅读:
    jquery ajax跨域取数据
    Python编写相关注意事项
    深入理解java.lang.String
    Java设计模式----迭代器模式
    Java设计模式----状态模式
    Java设计模式----观察者模式
    Java设计模式----适配器模式
    Java设计模式----外观模式
    Java设计模式----建造者模式
    Java设计模式----模板方法模式
  • 原文地址:https://www.cnblogs.com/shirly77/p/6679976.html
Copyright © 2020-2023  润新知