美文网首页
ECMAScript6简介2

ECMAScript6简介2

作者: 我不叫奇奇 | 来源:发表于2017-03-16 21:26 被阅读13次

    一. 字符串的一些扩展

    1. for...of遍历

      1. ES6为字符串添加了遍历器接口,似的字符串可以被for...of循环遍历

        for (let codePoint of 'foo') {
        console.log(codePoint)
        }
        // "f"
        // "o"
        // "o"

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

        var text = String.fromCodePoint(0x20BB7);

        for (let i = 0; i < text.length; i++) {
        console.log(text[i]);
        }
        // " "
        // " "

        for (let i of text) {
        console.log(i);
        }
        // "𠮷"

        ,字符串text只有一个字符,但是for循环会认为它包含两个字符(都不可打印),而for...of循环会正确识别出这一个字符。

    2. 查找字符串的三个新方法

      1. JavaScript只有indexOf方法,可以用来确定一个字符串是否包含在另一个字符串中。ES6又提供了三种新方法。

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

      2)三个方法都支持第二个参数,表示开始搜索的位置

      3)使用第二个参数n时,endsWith的行为与其他两个方法有所不同。它针对前n个字符,而其他两个方法针对从第n个位置直到字符串结束。

    3. repeat()

     1) repeat方法返回一个新字符串,表示将原字符串重复n次
    
            'x'.repeat(3) // "xxx"
                'hello'.repeat(2) // "hellohello"
                'na'.repeat(0) // "
    
     2) 参数如果是小数,会被取整。
    
              'na'.repeat(2.9) // "nana"
    
    1. padStart(). padEnd()

      1. ES2017引入了字符串补全长度的功能,如果某个字符串不够指定长度,会在头部或尾部补全。padStart()用于头部补全,padEnd()用于尾部补全。

        'x'.padStart(5, 'ab') // 'ababx'
        'x'.padStart(4, 'ab') // 'abax'
        
        'x'.padEnd(5, 'ab') // 'xabab'
        'x'.padEnd(4, 'ab') // 'xaba'
        
      2. 如果原字符串的长度,等于或大于指定的最小长度,则返回原字符串。

      3. 如果用来补全的字符串与原字符串,两者的长度之和超过了指定的最小长度,则会截去超出位数的补全字符串。

         'abc'.padStart(10, '0123456789')
          // '0123456abc'
        
      4. 如果省略第二个参数,默认使用空格补全长度。

      5. 用途

        a. padStart的常见用途是为数值补全指定位数。下面代码生成10位的数值字符串
        
          '1'.padStart(10, '0') // "0000000001"
          '12'.padStart(10, '0') // "0000000012"
          '123456'.padStart(10, '0') // "0000123456"
        
        b. 另一个用途是提示字符串格式。
        
          '12'.padStart(10, 'YYYY-MM-DD') // "YYYY-MM-12"
          '09-12'.padStart(10, 'YYYY-MM-DD') // "YYYY-09-12"
        
    2. 模板字符串

      1. 传统的JavaScript语言,输出模板通常是这样写的。

           $('#result').append(
            'There are <b>' + basket.count + '</b> ' +
            'items in your basket, ' +
            '<em>' + basket.onSale +
            '</em> are on sale!'
           );
        
      2. 上面这种写法相当繁琐不方便,ES6引入了模板字符串解决这个问题

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

      3. 模板字符串(template string)是增强版的字符串,用反引号(`)标识。它可以当作普通字符串使用,也可以用来定义多行字符串,或者在字符串中嵌入变量。

      4. 如果在模板字符串中需要使用反引号,则前面要用反斜杠转义。

      5. 如果使用模板字符串表示多行字符串,所有的空格和缩进都会被保留在输出之中,所有模板字符串的空格和换行,都是被保留的

      6. 模板字符串中嵌入变量,需要将变量名写在${}之中。

      7. 大括号内部可以放入任意的JavaScript表达式,可以进行运算,以及引用对象属性,也可以调用函数

      8. 如果需要引用模板字符串本身,在需要时执行,可以像下面这样写。

        // 写法一
        let str = 'return ' + 'Hello ${name}!';
        let func = new Function('name', str);
        func('Jack') // "Hello Jack!"

        // 写法二
        let str = '(name) => Hello ${name}!';
        let func = eval.call(null, str);
        func('Jack') // "Hello Jack!"

    3. 模板编译

    4. 通过模板字符串,生成正式模板的实例。

            var template = `
              <ul>
                <% for(var i=0; i < data.supplies.length; i++) { %>
                  <li><%= data.supplies[i] %></li>
                <% } %>
              </ul>
            `;
      

    上面代码在模板字符串之中,放置了一个常规模板。该模板使用<%...%>放置JavaScript代码,使用<%= ... %>输出JavaScript表达式

     2. 编译这个模板字符串
    
             function compile(template){
              var evalExpr = /<%=(.+?)%>/g;
              var expr = /<%([\s\S]+?)%>/g;
    
              template = template
                .replace(evalExpr, '`); \n  echo( $1 ); \n  echo(`')
                .replace(expr, '`); \n $1 \n  echo(`');
    
              template = 'echo(`' + template + '`);';
    
              var script =
              `(function parse(data){
                var output = "";
    
                function echo(html){
                  output += html;
                }
    
                ${ template }
    
                return output;
              })`;
    
              return script;
            }
    
             var parse = eval(compile(template));
    
             div.innerHTML = parse({ supplies: [ "broom", "mop", "cleaner" ] });
    
             //   <ul>
             //     <li>broom</li>
             //     <li>mop</li>
             //     <li>cleaner</li>
             //   </ul>
    

    二. 正则的扩展

    1. RegExp构造函数

      以前创建正则对象有两种方式

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

      现在多了一种

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

    2. 字符串的正则方法

    三. 数组的扩展

    1. Array.from

      1. 用于将两类对象转为真正的数组:类似数组的对象和可遍历的对象

        ES5的写法

           var arr1 = [].slice.call(arrayLike);
        

        ES6的写法

            let arr2 = Array.from(arrayLike);
        
      2. 实际应用中,常见的类似数组的对象是DOM操作返回的NodeList集合,以及函数内部的arguments对象。Array.from都可以将它们转为真正的数组。

            // NodeList对象
            let ps = document.querySelectorAll('p');
            Array.from(ps).forEach(function (p) {
              console.log(p);
            });
        
            // arguments对象
            function foo() {
              var args = Array.from(arguments);
              // ...
            }
        
      3. Array.from还可以接受第二个参数,作用类似与数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组

           Array.from(arrayLike, x => x * x);
            // 等同于
            Array.from(arrayLike).map(x => x * x);
        
            Array.from([1, 2, 3], (x) => x * x)
            // [1, 4, 9]
        
    2. Array.of()

      1. 用于将一组值,转换为数组

           Array.of(3, 11, 8) // [3,11,8]
            Array.of(3) // [3]
            Array.of(3).length // 1
        

        这个方法的主要目的,是弥补数组构造函数Array()的不足,因为参数个数的不同,会导致Array()的行为有差异

           Array() // []
            Array(3) // [, , ,]
            Array(3, 11, 8) // [3, 11, 8]
        
      2. Array.of基本上可以用来替代Array()或new Array(),并且不存在由于参数不同而导致的重载,他的行为非常统一,Array.of总是返回参数值组成的数组,如果没有参数,就返回一个空数组

    3. 数组实例的copyWithin()

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

        Array.prototype.copyWithin(target, start = 0, end = this.length)

        target(必需):从该位置开始替换数据

        start(可选): 从该位置开始读取数据,默认为0,如果为负值,表示倒数

        end(可选):到该位置前停止读取数据,默认等于数组长度,如果为负值,表示倒数

        这三个参数都应该是数值,如果不是,会自动转为数值

           [1, 2, 3, 4, 5].copyWithin(0, 3)
            // [4, 5, 3, 4, 5]
        

        上面代码表示将从3号位直到数组结束的成员(4和5),复制到从0号位开始的位置,结果覆盖了原来的1和2。

    4. 数组实例的find()

      1. 数组实例的find方法,用于找出第一个符合条件的数组成员,所有数组成员依次执行该回调函数,直到找出第一个返回值为true的成员,然后返回该成员。乳沟没有符合条件的成员,则返回undefined

           [1, 4, -5, 10].find((n) => n < 0)
        // -5
        
    5. 数组实例的fill

      1. fill方法使用给定值,填充一个数组

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

        new Array(3).fill(7)
        // [7, 7, 7]

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

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

        fill方法从1号位开始,向原数组填充7,到2号位之前结束。

    6. 数组实例的entries(),keys()和values()

      1)ES6提供三个新的方法——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"
      

      2)如果不使用for...of循环,可以手动调用遍历器对象的next方法,进行遍历。

    7. 数组实例的includes()

    四. 函数的扩展

    1. 函数参数的默认值

      1. ES6 允许为函数的参数设置默认值,即直接写在参数定义的后面。

        function log(x, y = 'World') {
             console.log(x, y);
           }
        
           log('Hello') // Hello World
           log('Hello', 'China') // Hello China
           log('Hello', '') // Hello
        
      2. 参数变量是默认声明的,所以不能用let或const再次声明。

      3),定义了默认值的参数,应该是函数的尾参数。因为这样比较容易看出来,到底省略了哪些参数。如果非尾部的参数设置默认值,实际上这个参数是没法省略的。

      1. 函数的length属性

      指定了默认值以后,函数的length属性,将返回没有指定默认值的参数个数。也就是说,指定了默认值后,length属性将失真。

      1. 应用

        利用参数默认值,可以指定一个参数不得省略,如果省略就抛出一个错误

            function throwIfMissing() {
               throw new Error('Missing parameter');
             }
        
             function foo(mustBeProvided = throwIfMissing()) {
               return mustBeProvided;
             }
        
             foo()
             // Error: Missing parameter
        
    2. rest参数

      1. ES6引入了rest参数(形式为"...变量名"),用于获取函数的多余参数,这样就不需要使用arguments对象了,rest参数搭配的变量师一个数组,该变量将多余的参数放入数组中

        function add(...values) {
        let sum = 0;

        for (var val of values) {
        sum += val;
        }

        return sum;
        }

        add(2, 5, 3) // 10

      2. 下面是一个利用 rest 参数改写数组push方法的例子

        function push(array, ...items) {
        items.forEach(function(item) {
        array.push(item);
        console.log(item);
        });
        }

        var a = [];
        push(a, 1, 2, 3)

      3. rest 参数之后不能再有其他参数(即只能是最后一个参数)

    3. 扩展运算符

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

          console.log(...[1, 2, 3])
            // 1 2 3
        
            console.log(1, ...[2, 3, 4], 5)
            // 1 2 3 4 5
        
            [...document.querySelectorAll('div')]
            // [<div>, <div>, <div>]
        
      2. 运算符主要用于函数调用。

           function push(array, ...items) {
             array.push(...items);
            }
        
            function add(x, y) {
             return x + y;
            }
        
            var numbers = [4, 38];
            add(...numbers) // 42
        
      3. 替代数组的apply方法

        // ES5的写法
        function f(x, y, z) {
        // ...
        }
        var args = [0, 1, 2];
        f.apply(null, args);

        // ES6的写法
        function f(x, y, z) {
        // ...
        }
        var args = [0, 1, 2];
        f(...args);

      4. 扩展运算符的应用

        合并数组

        // 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' ]
        
      5. 扩展运算符还可以将字符串转为真正的数组

            [...'hello']
         // [ "h", "e", "l", "l", "o" ]
        
      6. 何Iterator接口的对象,都可以用扩展运算符转为真正的数组。

          var nodeList = document.querySelectorAll('div');
        
         var array = [...nodeList];
        
    4. 箭头函数

      1. ES6允许使用“箭头”(=>)定义函数

          var f = v => v;
        
           ==>
        
         var f = function(v) {
              return v;
           };
        
      2. 如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分

          var f = () => 5;
            // 等同于
            var f = function () { return 5 };
        
            var sum = (num1, num2) => num1 + num2;
            // 等同于
            var sum = function(num1, num2) {
              return num1 + num2;
            };
        
      3. 如果箭头函数的代码块部分多于一条语句,就要使用大括号将它们括起来,并且使用return语句返回。

           var sum = (num1, num2) => { return num1 + num2; }
        
      4. 由于大括号被解释为代码块,所以如果箭头函数直接返回一个对象,必须在对象外面加上括号。

           var getTempItem = id => ({ id: id, name: "Temp" });
        
      5. 箭头函数使得表达更加简洁。

        上面代码只用了两行,就定义了两个简单的工具函数。如果不用箭头函数,可能就要占用多行,而且还不如现在这样写醒目。

      6. 箭头函数的一个用处是简化回调函数

         // 正常函数写法
            [1,2,3].map(function (x) {
              return x * x;
            });
        
            // 箭头函数写法
            [1,2,3].map(x => x * x);
        
      7. 使用注意点

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

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

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

    5. 绑定this

    五. 对象的扩展

    1. 属性的简洁表示法
     1) ES6允许直接写入变量和函数,作为对象的属性和方法
    
          var foo = 'bar';
          var baz = {foo};
          baz // {foo: "bar"}
    
     2) 方法也可以简写
    
              var o = {
                  method() {
                    return "Hello!";
                  }
                 };
    
     3) 实际例子
    
                 var birth = '2000/01/01';
    
                 var Person = {
    
                  name: '张三',
    
                  //等同于birth: birth
                  birth,
    
                  // 等同于hello: function ()...
                  hello() { console.log('我的名字是', this.name); }
    
                 };
    
    1. Object.assign()
     1) 用于对象的合并,将源对象(source)的所有可枚举属性,复制到目标对象(target)。
    
               var target = { a: 1 };
    
                 var source1 = { b: 2 };
                 var source2 = { c: 3 };
    
                 Object.assign(target, source1, source2);
                 target // {a:1, b:2, c:3}
    
     2) Object.assign拷贝的属性是有限制的,只拷贝源对象的自身属性(不拷贝继承属性)
    
     3) 注意点
    
         a. Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
    
              var obj1 = {a: {b: 1}};
              var obj2 = Object.assign({}, obj1);
    
              obj1.a.b = 2;
              obj2.a.b // 2
    
         b. 对于这种嵌套的对象,一旦遇到同名属性,Object.assign的处理方法是替换,而不是添加。
    
     4) 常见用途
     
        a. 为对象添加属性
    
             class Point {
              constructor(x, y) {
                Object.assign(this, {x, y});
              }
             }
    
        b. 为对象添加方法
    
             Object.assign(SomeClass.prototype, {
              someMethod(arg1, arg2) {
                ···
              },
              anotherMethod() {
                ···
              }
            });
    
        c. 克隆对象
    
             function clone(origin) {
              return Object.assign({}, origin);
             }
    
        d. 合并多个对象
    
             const merge = (target, ...sources) => Object.assign(target, ...sources);
    
    1. 属性的遍历
     1) for...in
    
         循环遍历对象自身的和可继承的可枚举属性
    
     2) object.keys(obj)
    
         Object.keys返回一个数组,包括对象自身的(不含继承的)所有可枚举属性(不含Symbol属性)。
    
    1. Object.keys()/Object.values()/Object.entries()
     1) Object.keys()
    
        ES5 引入了Object.keys方法,返回一个数组,成员是参数对象自身的(不含继承的)所有可遍历(enumerable)属性的键名

    相关文章

      网友评论

          本文标题:ECMAScript6简介2

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