美文网首页Nodejs学习笔记
Lesson-11 ES6 高级语法(2)

Lesson-11 ES6 高级语法(2)

作者: 阿瑟李 | 来源:发表于2015-08-12 11:58 被阅读69次

    Promise

    我觉得可以简单的把promise理解成一个拥有状态的队列,promise拥有三个状态Pending(进行中)、Resolved(已完成,又称Fulfilled)和Rejected(已失败,只要状态变为失败,就不会在执行后面的方法了

    var promise = new Promise(function(resolve, reject) {
      // ... some code
    
      if (/* 异步操作成功 */){
        resolve(value);
      } else {
        reject(error);
      }
    });
    

    在执行完上面的操作的时候 我们可以在后面添加 then 方法接受状态 then方法中的返回值可以成为下一个 then函数的参数

    promise.then(function(value) {
      // success
    }, function(value) {
      // failure
    });
    

    那么我们发现并没有队列这么一说啊 是的 promise 并不是真正的队列 而是通过then 函数 每次返回的新的Promise对象 和 链式语法形成一个队列 然后可以通过catch函数同意捕获错误

    getJSON("/post/1.json").then(function(post) {
      return getJSON(post.commentURL);
    }).then(function(comments) {
      // some code
    }).catch(function(error) {
      // 处理前面三个Promise产生的错误
    });
    

    还有可以通过all函数进行打包,Promise.all Promise.race 方法用于将多个Promise实例,包装成一个新的Promise实例。如果所有Promise 都成功 则表示成功 否则失败

    // 生成一个Promise对象的数组
    var promises = [2, 3, 5, 7, 11, 13].map(function(id){
      return getJSON("/post/" + id + ".json");
    });
    
    Promise.all(promises).then(function(posts) {
      // ...
    }).catch(function(reason){
      // ...
    });
    

    Generator函数与Promise的结合

    function getFoo () {
      return new Promise(function (resolve, reject){
        resolve('foo');
      });
    }
    
    var g = function* () {
      try {
        var foo = yield getFoo();
        console.log(foo);
      } catch (e) {
        console.log(e);
      }
    };
    
    function run (generator) {
      var it = generator();
    
      function go(result) {
        if (result.done) return result.value;
    
        return result.value.then(function (value) {
          return go(it.next(value));
        }, function (error) {
          return go(it.throw(value));
        });
      }
    
      go(it.next());
    }
    
    run(g);
    

    Class

    ES6提供了一种新的 类的写法

    class Point {
      constructor(){
        // ...
      }
    
      toString(){
        // ...
      }
    
      toValue(){
        // ...
      }
    }
    
    // 等同于
    
    Point.prototype = {
      toString(){},
      toValue(){}
    }
    

    可以使用下面方法拓展类方法

    class Point {
      constructor(){
        // ...
      }
    }
    
    Object.assign(Point.prototype, {
      toString(){},
      toValue(){}
    })
    

    新的构造函数像下面这样

    //定义类
    class Point {
    
      constructor(x, y) {
        this.x = x;
        this.y = y;
      }
    
      toString() {
        return '('+this.x+', '+this.y+')';
      }
    
    }
    
    var point = new Point(2, 3);
    
    point.toString() // (2, 3)
    
    point.hasOwnProperty('x') // true
    point.hasOwnProperty('y') // true
    point.hasOwnProperty('toString') // false
    point.__proto__.hasOwnProperty('toString') // true
    

    Class的继承
    使用extent继承 能直接使用 super.method()

    class ColorPoint extends Point {
    
      constructor(x, y, color) {
        super(x, y); // 调用父类的constructor(x, y)
        this.color = color;
      }
    
      toString() {
        return this.color + ' ' + super.toString(); // 调用父类的toString()
      }
    
    }
    

    类的prototype属性和proto属性
    在ES5中,每一个对象都有__proto__属性,指向对应的构造函数的prototype属性。Class作为构造函数的语法糖,同时有prototype属性和__proto__属性,因此同时存在两条继承链。

    (1)子类的__proto__属性,表示构造函数的继承,总是指向父类。

    (2)子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。

    类还可以这么继承

    class A {
    }
    
    class B {
    }
    
    // B的实例继承A的实例
    Object.setPrototypeOf(B.prototype, A.prototype);
    
    // B继承A的静态属性
    Object.setPrototypeOf(B, A);
    

    类方法 或者叫 类的静态方法

    class Foo {
      static classMethod() {
        return 'hello';
      }
    }
    
    Foo.classMethod() // 'hello'
    
    var foo = new Foo();
    foo.classMethod()
    

    属性的getter and setter

    class MyClass {
      constructor() {
        // ...
      }
      get prop() {
        return 'getter';
      }
      set prop(value) {
        console.log('setter: '+value);
      }
    }
    
    let inst = new MyClass();
    
    inst.prop = 123;
    // setter: 123
    
    inst.prop
    // 'getter'
    

    Proxy

    个人理解就是对类封装,能够捕获对类的一些操作,然后能够进行处理,有点类似监听

    var handler = {
      get: function(target, name) {
        if (name === 'prototype') return Object.prototype;
        return 'Hello, '+ name;
      },
      apply: function(target, thisBinding, args) { return args[0]; },
      construct: function(target, args) { return args[1]; }
    };
    
    var fproxy = new Proxy(function(x,y) {
      return x+y;
    },  handler);
    
    fproxy(1,2); // 1
    new fproxy(1,2); // 2
    fproxy.prototype; // Object.prototype
    fproxy.foo; // 'Hello, foo'
    
    

    Reflect

    个人理解是对类的一层简短封装 实现一系列的功能

    var obj = {
      get foo() { return this.bar(); },
      bar: function() { ... }
    }
    
    // 下面语句会让 this.bar()
    // 变成调用 wrapper.bar()
    Reflect.get(obj, "foo", wrapper);
    

    Symbol

    Symbol是一种新的数据类型 其他几种是 前七种是:数值、字符串、布尔值、数组、对象、函数、undefined。
    可以把它作为属性名

    var mySymbol = Symbol();
    
    // 第一种写法
    var a = {};
    a[mySymbol] = 'Hello!';
    
    // 第二种写法
    var a = {
      [mySymbol]: 'Hello!'
    };
    
    // 第三种写法
    var a = {};
    Object.defineProperty(a, mySymbol, { value: 'Hello!' });
    
    // 以上写法都得到同样结果
    a[mySymbol] // "Hello!"
    

    Symbol作为属性名,该属性不会出现在for...in、for...of循环中,也不会被Object.keys()
    、Object.getOwnPropertyNames()
    返回。但是,它也不是私有属性,有一个Object.getOwnPropertySymbols方法,可以获取指定对象的所有Symbol属性名。
    除了定义自己使用的Symbol值以外,ES6还提供一些内置的Symbol值,指向语言内部使用的方法。

    相关文章

      网友评论

        本文标题:Lesson-11 ES6 高级语法(2)

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