zoukankan      html  css  js  c++  java
  • es2015及es2017对我们的编程方式造成了什么影响?

    记一些写代码中用得到的es6+语法,至于什么正则的拓展,数组的什么fill方法,对我们来说用处不大,就不提及了。
    还有es6的import模块和class模块,这些在各种框架中都有体现,而且语法简单,也不提及。仅写一下对当前项目的影响。

    let/const

    var a = [];
    for (var i = 0; i < 10; i++) {
      a[i] = function () {
        console.log(i);
      };
    }
    a[6](); // 10
    

    导致了typeof再也不是完全安全的操作了

    typeof a;
    let a; // error
    

    块级作用域以后就不需要自执行函数了

    // IIFE 写法
    (function () {
      var tmp = ...;
      ...
    }());
    
    // 块级作用域写法
    {
      let tmp = ...;
      ...
    }
    

    解构赋值

    let [a, b, c] = [1, 2, 3];
    相当于
    var _a = [1, 2, 3], a = _a[0], b = _a[1], c = _a[2];
    
    var {x, y = 5} = {x: 1};
    x // 1
    y // 5
    
    function add([x, y]){
      return x + y;
    }
    
    add([1, 2]); // 3
    
    let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
    x // 1
    y // 2
    z // { a: 3, b: 4 }
    

    函数的拓展

    • 参数默认值
    • rest 参数
    function add(...values) {
      let sum = 0;
      // values = [2,5,3];
      for (var val of values) {
        sum += val;
      }
    
      return sum;
    }
    
    add(2, 5, 3) // 10
    
    • 箭头函数
    var f = v => v;
    相当于
    var f = function(v) {
      return v;
    };
    
    var f = v => (a) => "c";
    相当于
    var f = function (v) { 
      return function (a) { 
        return "c";
      };
    };
    
    var f = v => console.log(v);
    var f = v => {console.log(v)};
    var f = v => { return console.log(v)};// 这3种方式有什么区别?
    

    对象拓展

    Object.assign

    const target = { a: 1 };
    
    const source1 = { b: 2 };
    const source2 = { c: 3 };
    
    Object.assign(target, source1, source2);
    target // {a:1, b:2, c:3}
    
    =>
    
    function extend(obj, ext) { // 用assign写$.extend
      return Object.assign({}, obj, ext);
    }
    

    generator

    • Generator 函数是 ES6 提供的一种异步编程解决方案。
    • 执行 Generator 函数会返回一个遍历器对象
    function* helloWorldGenerator() {
      yield 'hello';
      yield 'world';
      return 'ending';
    }
    
    var hw = helloWorldGenerator();
    
    hw.next()
    // { value: 'hello', done: false }
    hw.next()
    // { value: 'world', done: false }
    hw.next()
    // { value: 'ending', done: true }
    hw.next()
    // { value: undefined, done: true }
    

    用for of循环遍历

    for (let v of hw){
        console.log(v);
    }
    // hello world
    

    generator函数的yield没有返回,next方法可以带一个参数,该参数就会被当作上一个yield表达式的返回值。

    function* helloWorldGenerator() {
        console.log('Hello' + (yield 123));
        yield 'world';
        return 'ending';
      }
    
       var hw = helloWorldGenerator();
        console.log( hw.next('1'));// 第一个next的参数是没用的,因为没有上一个yield
        console.log( hw.next('2'));
    
        // { value: 123, done: false }
        // Hello2
        //{ value: 'world', done: false }
    

    因为都是iterator遍历器对象,所以基于for of的解构赋值也能用,但是return的done状态是true,所以下面这段代码ending为undefined

    function* helloWorldGenerator() {
        yield 'hello'
        yield 'world';
        return 'ending';
      }
    
      var hw = helloWorldGenerator();
      let [hello,world,ending ] = hw;
      console.log(hello,world,ending );
    

    也可以函数外return,参数为其value

    function* helloWorldGenerator() {
        yield 'hello'
        yield 'world';
        return 'ending';
      }
    
      var hw = helloWorldGenerator();
       console.log( hw.return('a'));// { value: 'a', done: true }
    

    而且

    function* bar() {
      yield 'x';
      yield* foo();
      yield 'y';
    }
    ===
    function* bar() {
      yield 'x';
      for (let v of foo()) {
        yield v;
      }
      yield 'y';
    }
    

    给object添加iterator接口,使其能够被for of遍历出来:

    var obj = {
        a:1,b:2,c:3,d:4
    };
    obj[Symbol.iterator] =  () => {
        var keys = Object.keys(obj);
        var current = 0;
        return {
          next: function () {
                var res = {
                    value: obj[keys[current]],
                    done:  keys[current] ?false:true
                };
                console.log(res)
                current++;
                return res;
            }
        };
    };
    for (let v of obj){
        console.log(v);
    }
    思考一下,怎么把iterator函数里的obj换成this?
    

    那么如何完成这个操作:

    function* a(){
        yield "a";
    }
    function* b(){
        yield a();
    }
    b()______;
    //填什么得到a()中的“a”?
    

    es8的主要特性

    其中js的多线程阿,共享内存对我们影响不大,但是还是稍微提及一下,主要影响就是async函数了

    async

    • 是 Generator 函数的语法糖。
    • 内置执行器
    • 要求await后面是promise
    • 语义性好
    async function main() {
      try {
        const val1 = await a();
        const val2 = await b(val1);
        const val3 = await c(val1, val2);
    
        console.log('Final: ', val3);
      }
      catch (err) {
        console.error(err);
      }
    }
    

    a,b,c是3个异步操作,这样会顺序执行,a,b,c。如果希望abc同时执行也可以写为:

    // 写法一
    let [foo, bar] = await Promise.all([a(), b(), c()]);
    
    // 写法二
    let aP = a();
    let bP = b();
    let cP = c();
    let foo = await aP;
    let bar = await bp;
    let res = await cP;
    
    function PromiseFactory(delay){
        return (name) => new Promise((rs,rj) => {
                setTimeout(()=>{
                    console.log(delay,'over');
                    rs(name);
                },delay)
            })
    }
    var a = PromiseFactory(1000);
    var b = PromiseFactory(2000);
    var c = PromiseFactory(3000);
    async function gen(){
        let aP = a('a');
        let bP = b('b');
        let cP = c('c');
        let foo = await aP;
        let bar = await bP;
        let res = await cP;
        return console.log(foo,bar, res);
    }
    gen();
    

    共享内存和Atomics

    此功能引入了一个新的低级别Atomics命名空间对象和一个SharedArrayBuffer构造函数,来作为更高级别并发抽象的原始构建块。

    • 这使开发人员能够共享多个service worker和核心线程之间的SharedArrayBuffer对象的数据。
    • 这种引入带来了巨大的益处,因为可以更轻松地在worker之间共享数据,从而可以改善worker之间的协调。

    Atomics

    当内存共享时,内存中的数据块可能被多个线程同时读写。Atomic 操作保障了数据读写符合预期,即下一个操作一定会在上一个操作结束后才开始,操作也不会被中断。

    1. Atomics.add() // 将数组指定位置上的值加上一个给定值。返回这个位置上的旧值。
    2. Atomics.and() // 对数组指定位置上的值进行位与操作。返回这个位置上的旧值。
    3. Atomics.compareExchange() // 如果数组中特定位置的值与给定的值相等,则更新为另一个指定的值。返回这个位置上的旧值
    4. Atomics.store() // 将给定值存在数组的指定位置。返回这个“给定值”。
    5. ...

    SharedArrayBuffer

    对象用来表示一个泛型的,固定长度的原生二进制数据缓冲区,类似于 ArrayBuffer 对象。但在某种程度上,它们能被用于在共享内存上创建视图。与 ArrayBuffer 不同的是,SharedArrayBuffer 不能被移除。

    • new SharedArrayBuffer(length)

    字符串填充

    padStart 和 padEnd 。正如其名,这俩函数的作用就是在字符串的头部和尾部增加新的字符串,并且返回一个具有指定长度的新的符串。

    'es8'.padStart(2);          // 'es8'
    'es8'.padStart(5);          // '  es8'
    'es8'.padStart(6, 'woof');  // 'wooes8'
    
    'es8'.padEnd(2);          // 'es8'
    'es8'.padEnd(5);          // 'es8  '
    'es8'.padEnd(6, 'woof');  // 'es8woo'
    

    Object values和entries函数

    Object.values类似Object.keys的返回。

    const obj = { x: 'xxx', y: 1 };
    Object.values(obj); // ['xxx', 1]
    
    const obj = ['e', 's', '8']; // same as { 0: 'e', 1: 's', 2: '8' };
    Object.values(obj); // ['e', 's', '8']
    

    Object.entries

    const obj = { x: 'xxx', y: 1 };
    Object.entries(obj); // [['x', 'xxx'], ['y', 1]]
    
    const obj = ['e', 's', '8'];
    Object.entries(obj); // [['0', 'e'], ['1', 's'], ['2', '8']]
    

    getOwnPropertyDescriptors

    const obj = { 
      get es7() { return 777; },
      get es8() { return 888; }
    };
    Object.getOwnPropertyDescriptor(obj);
    // {
    //   es7: {
    //     configurable: true,
    //     enumerable: true,
    //     get: function es7(){}, //the getter function
    //     set: undefined
    //   },
    //   es8: {
    //     configurable: true,
    //     enumerable: true,
    //     get: function es8(){}, //the getter function
    //     set: undefined
    //   }
    // }
    

    结尾逗号

    function es8(var1, var2, var3,) {
      // ...
    }
    es8(10, 20, 30,);
    
  • 相关阅读:
    "use strict"详解
    HTML5 文件上传
    jquery $(document).ready() 与window.onload的区别
    前端面试题——错题集
    css-子div设置margin-top影响父div
    常见的dom操作----原生JavaScript与jQuery
    前端面试题——错题集
    JavaScript正则表达式知识点
    越权漏洞
    php反系列化原理和演示
  • 原文地址:https://www.cnblogs.com/dh-dh/p/7660338.html
Copyright © 2011-2022 走看看