1)generator 是ES6提供的一种一部解决方案。是一个状态机和遍历器生成函数。其语法如下:
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 }
ps:ES6 没有规定,function关键字与函数名之间的星号,写在哪个位置。这导致下面的写法都能通过。
function * foo(x, y) { ··· }
function *foo(x, y) { ··· }
function* foo(x, y) { ··· }
function*foo(x, y) { ··· }
//循环一下
var myisDone=false;
var myitem;
while(!myisDone){
myitem=hw.next();
myisDone=myitem.done;
console.log(myitem.value);
}
2)yield 表达式
function* gen() {
yield 123 + 456;
}
//只有调用next方法yield后面的i表达式才会执行。
generator函数也可以不用yield表达式,这样它就变成一个暂缓执行函数,
function* f() {
console.log('执行了!')
}
var generator = f();
setTimeout(function () {
generator.next()
}, 2000);
//此处f是一个generator函数,只有在调用next方法后才会执行内部语句‘console.log('执行了!')’。
另外需要注意,yield表达式只能用在 Generator 函数里面,用在其他地方都会报错。
(function (){
yield 1;
})()
// SyntaxError: Unexpected number
给一个对象手动添加遍历器生成方法
//写法一
var obj={a:1,b:2,c:3}
obj[Symbol.iterator]=function* (){
for(let i in obj){
yield [i,obj[i]]
}
}
//写法二
var obj={a:1,b:2,c:3,
*[Symbol.iterator] (){
for(let i in obj){
yield [i,obj[i]]
}
}
}
//使用 for of或者...进行遍历
for(let [key,value] of obj){
console.log(key,value)
}
console.log(...obj)
ps:另外,yield表达式如果用在另一个表达式之中,必须放在圆括号里面。
function* demo() {
console.log('Hello' + yield); // SyntaxError
console.log('Hello' + yield 123); // SyntaxError
console.log('Hello' + (yield)); // OK
console.log('Hello' + (yield 123)); // OK
}
yield表达式用作函数参数或放在赋值表达式的右边,可以不加括号。
function* demo() {
foo(yield 'a', yield 'b'); // OK
let input = yield; // OK
}
3)next 方法的参数
function* f() {
for(var i = 0; true; i++) {
var reset = yield i;
if(reset) { i = -1; }
}
}
var g = f();
g.next() // { value: 0, done: false }
g.next() // { value: 1, done: false }
g.next(true) // { value: 0, done: false }
//next方法的参数表示上一个yield表达式的返回值.
这个功能有很重要的语法意义。Generator 函数从暂停状态到恢复运行,它的上下文状态(context)是不变的。通过next方法的参数,就有办法在 Generator 函数开始运行之后,继续向函数体内部注入值。也就是说,可以在 Generator 函数运行的不同阶段,从外部向内部注入不同的值,从而调整函数行为。
4)
Array.from()可以将两类对象转化为数组,包括类数组对象,以及可遍历(iterable)对象(包括ES6新增的数据结构Set,Map)
let arrayLike = {
'0': 'a',
'1': 'b',
'2': 'c',
length: 3
};
// ES5的写法
var arr1 = [].slice.call(arrayLike); // ['a', 'b', 'c']
// ES6的写法
let arr2 = Array.from(arrayLike); // ['a', 'b', 'c']