ES6之Generator(2)知识点总结(九)

本文详细介绍了ES6中Generator函数的使用方法,包括throw()和return()方法的应用及注意事项,通过具体示例展示了如何在函数体外抛出错误并在内部捕获。

记笔记,主要是为了提高学习效率,避免只看不动手,领略不到书的精髓,忽略到书中的重点知识,本文学习主要是根据阮一峰大神走的,很感谢阮一峰大神的无私奉献。如果想要了解更详细的关于本节的内容可以看阮一峰大神的ES6官网http://es6.ruanyifeng.com/#docs/generator

嗯、今天主要学的是Generator函数返回的遍历器对象的方法:throw()、return()

Generator函数返回的遍历器对象,都有一个throw方法,可以在函数体外抛出错误,然后再Generator函数体内捕获。

throw方法可以接收一个参数,该参数会被catch语句接收,建议抛出Error对象的实例

var g = function *(){
    try{
        yield "welcome zhengzhou";
    }catch(e){
       console.log("内部捕获",e);//内部捕获 leo
    }
}
var p = g();
console.log(p.next());//{ value: "welcome zhengzhou", done: false }
try{
    p.throw('leo');
    p.throw('donna');

}catch(e){
    console.log("外部捕获",e);//外部捕获 donna
}

上面代码中,遍历器对象p连续抛出两个错误。第一个错误被Generator函数体内的catch语句捕获。p第二次抛出错误,由于Generator函数体内部的catch语句已经执行过了,不会再捕获到这个错误了,所以这个错误就被抛出了Generator函数体外,被函数体外的catch语句捕获

再看个

var g = function *(){
    try{
        yield "welcome zhengzhou";
    }catch(e){
       console.log("内部捕获",e);
    }
}
var p = g();
console.log(p.next());//{ value: "welcome zhengzhou", done: false }
console.log(p.next());//{ value: undefined, done: true }
console.log(p.next());//{ value: undefined, done: true }
try{
    p.throw('leo');
    p.throw('donna');

}catch(e){
    console.log("外部捕获",e);//外部捕获 leo
}

因为上面的Generator函数的遍历器对象调用了3次next方法,所以,当执行throw方法的时候,Generator函数对象已经遍历完成,所以,相当于Generator函数内部没有部署try…catch代码块,那么throw方法抛出的错误将被外部try…catch代码块捕获。函数体外的catch语句块,捕获了抛出的“leo”错误以后,就不会再继续try代码块里面剩余的语句了。

注意:如果Generator函数内部和外部都没有部署try…catch语句,那么程序将报错,直接中断执行。

throw方法被捕获以后,会附带执行下一条yield表达式,也就是说,会附带执行一次next方法。

var g = function *(){
    try{
        yield "welcome zhengzhou";
    }catch(e){
       console.log("内部捕获",e);
       yield "gygq";
    }
}
var p = g();
console.log(p.next());

try{
    console.log(p.throw('leo'));
    p.throw('donna');

}catch(e){
    console.log("外部捕获",e);
}
     //Object { value: "welcome zhengzhou", done: false }
    //内部捕获 leo
    // { value: "gygq", done: false }
    //外部捕获 donna
从上面的打印结果,可以看出,throw方法抛出以后,它下面的yield表达式也被执行了
var g = function *(){
    try{
        yield "welcome zhengzhou";
    }catch(e){
       console.log("内部捕获",e);
       yield "gygq";
    }
    yield "hello";
}
var p = g();
console.log(p.next());

try{
    console.log(p.throw('leo'));
}catch(e){
    console.log("外部捕获",e);
}
console.log(p.next());
     //Object { value: "welcome zhengzhou", done: false }
    //内部捕获 leo
    // { value: "gygq", done: false }
    //{ value: hello, done: false }
从上面的打印结果可以看出,,只要Generator函数内部部署了try…catch代码块,那么遍历器的throw方法抛出的错误,不影响下一次的遍历。

var g = function *(){
    try{
        yield "welcome zhengzhou";
    }catch(e){
       console.log("内部捕获",e);
       yield "gygq";
    }
    yield "hello";
}
var p = g();
console.log(p.next());

try{
    console.log(p.throw('leo'));
    p.throw('donna');

}catch(e){
    console.log("外部捕获",e);
}
console.log(p.next());
     //Object { value: "welcome zhengzhou", done: false }
    //内部捕获 leo
    // { value: "gygq", done: false }
    //外部捕获 donna
    //{ value: undefined, done: true }

从上面的结果中我们发现,当我们抛出的错误被Generator函数体外的try…catch捕获以后,又去执行p.next()方法,value属性的值为undefined,done属性的结果为true,而Generator函数体内还有yield表达式没有执行完。这是因为一旦Generator执行过程中抛出错误,且没有被内部捕获,就不会再执行下去了。如果此后还有next方法将返回一个value属性等于undefined,done属性为true的对象,即JavaScript引擎认为这个Generator已经运行结束了。

return方法:

Generator函数返回的遍历器对象,还有一个return方法,可以返回给定的值,并且最终遍历Generator函数。

var g = function *(){
    yield "leo";
    yield "donna";
    yield "hello";
}
var p = g();
console.log(p.next());
console.log(p.return("hello"));
console.log(p.next());
     //Object { value: "leo", done: false }
    //{ value: hello, done: true }
    //{ value: undefined, done: true }

上面的代码中,遍历器对象p调用了return方法后,返回值的value属性就是return方法的参数hello,并且,Generator函数的遍历就中止了,返回值的done属性为true,以后再调用next方法,done属性总是返回true。

如果return方法调用是,不提供参数,则返回值的value属性为undefined。

如果Generator函数内部有try…finally代码块,那么return方法会推迟finally代码块执行完再执行

var g = function *(){
    yield "leo";
    try{
        yield "donna";
    }finally{
        yield "hello";
    }
    yield "lalalal";

}
var p = g();
console.log(p.next());
console.log(p.next());
console.log(p.return("world"));
console.log(p.next());
console.log(p.next());

     //Object { value: "leo", done: false }
    //{ value: donna, done: false }
    //{ value: hello, done: false }
//{ value: hello, world: true }
//{ value: undefined, done: true }

上面代码中,调用return方法后,就开始执行finally代码块,然后等到finally代码块执行完,再执行return方法。

再看一段代码

var g = function *(){
    yield "leo";
    try{
        yield "donna";
    }finally{
        yield "hello";
    }
    yield "lalalal";

}
var p = g();
console.log(p.next());
console.log(p.return());
console.log(p.next());
console.log(p.next());

     //Object { value: "leo", done: false }
    //{ value: undefined, done: true }
//{ value: undefined, done: true }
//{ value: undefined, done: true }
我们发现上面代码,在还没有开始执行try…finally代码块的时候就调用了return方法,那么此时是不会等到finally代码块执行完Generator函数的遍历就中止了。所以,只有当调用return方法的时候,Generator函数正在执行try…finally的时候,return方法会等到finally代码块执行完执行,否则都是直接执行。


### JavaScript ES6 关键知识点总结 以下是关于 JavaScript ES6 的关键知识点总结,涵盖语言特性、语法改进以及实际应用中的开发技巧: #### 1. 模板字符串 模板字符串允许使用反引号(`` ` ``)包裹字符串,并支持多行书写和变量插值。在 ES6 以前,字符串拼接通常需要使用加号(`+`),而在 ES6 中可以通过 `${}` 插入变量或表达式[^2]。 ```javascript const name = 'css'; const career = 'coder'; const hobby = ['coding', 'writing']; const finalString = `my name is ${name}, I work as a ${career}, I love ${hobby[0]} and ${hobby[1]}`; console.log(finalString); ``` #### 2. 箭头函数 箭头函数提供了一种更简洁的函数定义方式,同时解决了传统函数中 `this` 绑定问题。箭头函数不绑定自己的 `this`,而是继承自外部作用域[^1]。 ```javascript const add = (a, b) => a + b; console.log(add(3, 5)); // 输出 8 ``` #### 3. 解构赋值 解构赋值可以从数组或对象中提取数据并赋值给变量,简化了数据处理逻辑[^1]。 ```javascript const [x, y] = [1, 2]; console.log(x, y); // 输出 1, 2 const { name, age } = { name: 'Alice', age: 25 }; console.log(name, age); // 输出 Alice, 25 ``` #### 4. 类与继承 ES6 引入了类的概念,通过 `class` 关键字定义类,并支持继承和方法调用。子类可以使用 `super` 调用父类的构造函数和方法[^3]。 ```javascript class Dad { constructor(name) { this.name = name; } fun() { console.log('父类的成员方法...'); } } class Son extends Dad { constructor(name) { super(name); } hobby() { console.log('篮球'); } show() { super.fun(); console.log(`姓名:${this.name}`); } } const s1 = new Son('张三'); s1.show(); // 输出 "父类的成员方法..." 和 "姓名:张三" ``` #### 5. 默认参数 函数参数可以设置默认值,避免因未传参导致的 `undefined` 问题[^1]。 ```javascript function greet(name = 'Guest') { console.log(`Hello, ${name}!`); } greet(); // 输出 "Hello, Guest!" ``` #### 6. 扩展运算符 扩展运算符(`...`)用于展开数组或对象,便于合并、拷贝或传递参数[^1]。 ```javascript const arr1 = [1, 2, 3]; const arr2 = [...arr1, 4, 5]; console.log(arr2); // 输出 [1, 2, 3, 4, 5] const obj1 = { a: 1, b: 2 }; const obj2 = { ...obj1, c: 3 }; console.log(obj2); // 输出 { a: 1, b: 2, c: 3 } ``` #### 7. Promise Promise 提供了一种更好的异步编程解决方案,替代了传统的回调函数[^1]。 ```javascript const promise = new Promise((resolve, reject) => { setTimeout(() => resolve('成功'), 1000); }); promise.then(result => console.log(result)); // 输出 "成功"(1秒后) ``` #### 8. 模块化 ES6 支持模块化开发,通过 `import` 和 `export` 实现代码复用和组织。 ```javascript // math.js export function add(a, b) { return a + b; } // main.js import { add } from './math.js'; console.log(add(2, 3)); // 输出 5 ``` #### 9. Map 和 Set ES6 引入了新的数据结构 `Map` 和 `Set`,分别用于存储键值对和唯一值集合[^1]。 ```javascript const map = new Map(); map.set('name', 'Alice'); console.log(map.get('name')); // 输出 "Alice" const set = new Set([1, 2, 3, 3]); console.log(set.size); // 输出 3 ``` #### 10. Iterator 和 Generator Iterator 是一种遍历机制,而 Generator 是一种特殊的函数,允许函数暂停和恢复执行[^1]。 ```javascript function* generator() { yield 1; yield 2; yield 3; } const gen = generator(); console.log(gen.next().value); // 输出 1 console.log(gen.next().value); // 输出 2 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值