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

Lesson-8 ES6 高级语法(1)

作者: 阿瑟李 | 来源:发表于2015-08-10 12:54 被阅读584次

    新增关键字 let const

    首先必须要记住的是这里的let和swift中的let完 全不同,并不是表示常量,而是var的变种

    • 不允许重复声明
    • 不会提升 也就是说在声明这个变量之前是不能使用的
      *在ES6中添加块级作用域,简单理解就是所有的{}中间,let const都可以响应这些作用域,而var是不能响应的 他只能响应全局和函数作用域
      const 表示常量 不能修改 其他和let一样 而且如果需要为模块添加对外暴露的常量 如下定义 export const A = 1;

    允许结构赋值

    • 可以缺省
    • 可以设置默认值
    var [a, b, c] = [1, 2, 3];
    let [,,third] = ["foo", "bar", "baz"];
    let [a, [b], d] = [1, [2, 3], 4];
    
    [x, y='b'] = ['a'] // x='a', y='b'
    [x, y='b'] = ['a', undefined] // x='a', y='b'
    
    let [v1, v2, ..., vN ] = array;
    [a, b, c] = new Set(["a", "b", "c"])
    
    function* fibs() {
      var a = 0;
      var b = 1;
      while (true) {
        yield a;
        [a, b] = [b, a + b];
      }
    }
    
    var [first, second, third, fourth, fifth, sixth] = fibs();
    sixth // 5
    

    上面代码中,fibs是一个Generator函数,原生具有Iterator接口。解构赋值会依次从这个接口获取值。
    解构赋值还可以用在对象的赋值上

    //直接赋值
    var { foo, bar } = { foo: "aaa", bar: "bbb" };
    //属性名不一样的时候
    var { foo: baz } = { foo: "aaa", bar: "bbb" };
    //
    

    这个东西可以直接交换 也可以返回多个值 有点类似swift中的元组

    Iterator(遍历器)

    简单来说就是获取这个类的某个指针,然后可以调用他的next方法进行遍历

    Iterator的作用有三个:一是为各种数据结构,提供一个统一的、简便的访问接口;二是使得数据结构的成员能够按某种次序排列;三是ES6创造了一种新的遍历命令for...of循环,Iterator接口主要供for...of消费。

    let arr = ['a', 'b', 'c'];
    let iter = arr[Symbol.iterator]();
    
    iter.next() // { value: 'a', done: false }
    iter.next() // { value: 'b', done: false }
    iter.next() // { value: 'c', done: false }
    iter.next() // { value: undefined, done: true }
    

    自已定义的类满足遍历器

    class RangeIterator {
      constructor(start, stop) {
        this.value = start;
        this.stop = stop;
      }
    
      [Symbol.iterator]() { return this; }
    
      next() {
        var value = this.value;
        if (value < this.stop) {
          this.value++;
          return {done: false, value: value};
        } else {
          return {done: true, value: undefined};
        }
      }
    }
    
    function range(start, stop) {
      return new RangeIterator(start, stop);
    }
    
    for (var value of range(0, 3)) {
      console.log(value);
    }
    

    在 generator 函数中 每次遍历返回一个 yield, 但是如果出现 yield* 后面跟的是一个可遍历的结构,它会调用该结构的遍历器接口。

    let generator = function* () {
      yield 1;
      yield* [2,3,4]; //use an iterable, is looped, and added as yields
      yield 5;
    };
    
    var iterator = generator();
    
    iterator.next() // { value: 1, done: false }
    iterator.next() // { value: 2, done: false }
    iterator.next() // { value: 3, done: false }
    iterator.next() // { value: 4, done: false }
    iterator.next() // { value: 5, done: false }
    iterator.next() // { value: undefined, done: true }
    
    var myIterable = {};
    
    myIterable[Symbol.iterator] = function* () {
      yield 1;
      yield 2;
      yield 3;
    };
    [...myIterable] // [1, 2, 3]
    
    // 或者采用下面的简洁写法
    
    let obj = {
      * [Symbol.iterator]() {
        yield 'hello';
        yield 'world';
      }
    };
    
    for (let x of obj) {
      console.log(x);
    }
    // hello
    // world
    

    可以使用for...of循环遍历器

    可以用for...of遍历集合 不能遍历对象

    Generator 函数

    Generator函数有多种理解角度。从语法上,首先可以把它理解成一个函数的内部状态的遍历器(也就是说,Generator函数是一个状态机)。它每调用一次,就进入下一个内部状态。Generator函数可以控制内部状态的变化,依次遍历这些状态。

    形式上,Generator函数是一个普通函数,但是有两个特征。一是,function命令与函数名之间有一个星号;二是,函数体内部使用yield语句,定义遍历器的每个成员,即不同的内部状态(yield语句在英语里的意思就是“产出”)。

    任意一个对象的Symbol.iterator属性,等于该对象的遍历器函数,调用该函数会返回该对象的一个遍历器。

    yield

    next的参数就是yield的返回值

    function* foo(x) {
      var y = 2 * (yield (x + 1));
      var z = yield (y / 3);
      return (x + y + z);
    }
    
    var it = foo(5);
    
    it.next()
    // { value:6, done:false }
    it.next(12)
    // { value:8, done:false }
    it.next(13)
    // { value:42, done:true }
    

    内部捕获异常

    var g = function* () {
      while (true) {
        try {
          yield;
        } catch (e) {
          if (e != 'a') throw e;
          console.log('内部捕获', e);
        }
      }
    };
    
    var i = g();
    i.next();
    
    try {
      i.throw('a');
      i.throw('b');
    } catch (e) {
      console.log('外部捕获', e);
    }
    // 内部捕获 a
    // 外部捕获 b
    

    yield*语句

    如果yield命令后面跟的是一个遍历器,需要在yield命令后面加上星号,表明它返回的是一个遍历器。这被称为yield*语句。

    相关文章

      网友评论

        本文标题:Lesson-8 ES6 高级语法(1)

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