Nodejs学习笔记

Lesson-8 ES6 高级语法(1)

2015-08-10  本文已影响584人  阿瑟李

新增关键字 let const

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

允许结构赋值

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*语句。

上一篇下一篇

猜你喜欢

热点阅读