ES6学习总结(四)

与大多数面向对象语言不同,js创建之初不支持类,在ES1-ES5很多库创建了一些工具来让js显得好像支持类 ,直到ES6正式引入类。
ES6类的声明是以class关键字开始后面紧跟类名,类声明中有constructor方法可以直接定义一个构造器。

class personClass{
     constructor(name) {
        this.name = name 
    }
}

类和之前的函数构造器有着很多的区别
1、类声明不会被提升,其行为和let类似,因此在程序执行到达声明处前,类会存在于暂时性死区内。
2、类声明中的所有代码会自动运行在严格模式下,并且无法退出严格模式。
3、类中的所有方法都是不可枚举的,函数构造器中必须使用object.defineProperty()才能将方法变为不可枚举。
4、类的所有方法没有[[constructor]],因此不能使用new来调用他们。
5、调用类构造器时必须使用new。
6、试图在类方法内部重写类名会报错。
类中的生成器方法
类中只需要在方法名称前附加一个"*"号就能定义一个生成器

class MyClass{
    *createIterator() {
        yield 1;
        yield 2;
        yield 3;
   }
}
let instance = new MyClass();
let iterator = instance.createIterator();

静态成员

//在ES5及更早版本中,是直接在构造器上添加额外方法来模拟静态成员
function PersonType(name) {
   this.name = name
}
PersonType.create = function(name) {
   return new PersonType(name)
}
//像PersonType.create()会被认定为一个静态方法,它的数据不依赖PersonType任何实例
//ES6中静态方法的表示
class PersonType{
    constructor(name) {
         this.name = name 
    }
    static create(name) {
        return new PersonType
    }
}

继承
在出现类之前,继承的实现很繁复,类中提供了extends关键字来指定当前类所需要继承的函数,还能调用super()方法访问基类构造器。

// ES5以及之前构造器间的继承实现
function PersonClass(name){
    this.length = length;
}
PersonClass.prototype.getName = function () {
  return this.name
}
function Person(name){
   PersonClass.call(this,name)
}
Person.prototype = Object.create(PersonClass.prototype, {
    constructor {
        value: Person,
        enumerable: true,
        writable: true,
        configurable: true
    }
})
// ES6中继承的实现方法
class PersonClass {
   constructor(name) {
       this.name = name
   }
   getName(){
       return this.name
   }
}
class Person extends PersonClass{
    constructor(name) {
    // 与上例 Person.class(this, name)相同
       super(name);
    }
}
var digua = new Person('digua');
console.log(digua.getName) // digua

迭代器与生成器

迭代器
ES6中加入了迭代器,它是对高效处理集合数据一种补充,所有的迭代器都含有next()方法,它返回两个值,第一个值时集合中的下一项(value),第二项是是否还有更多的值供使用(done)。迭代器中可以选择实现一个throw()方法来抛出错误,ES6中新增了for-of来和迭代器协同工作,扩展运算符(…)也使用了它,同时它对异步操作也有一定意义。
生成器
生成器是能返回一个迭代器的函数,它的表达方法是function后加一个(*),同时使用yield来表明每一步结果。
例子

function* create(){
   yield 1;
   yield 2;
   yield 4;
}
let obj = create()
console.log(obj.next())  // {value: 1, done: false}
console.log(obj.next())  // {value: 2, done: false}
console.log(obj.next())  // {value: 4, done: false}
console.log(obj.next())  // {value: undefined, done: true}
// next 中可以传值,当第一个参数被传递给next方法时,它会成为生成器内部yield语句的值,注意第一次调用时任意参数会被忽略。
function* create2(){
   let first = yield 1;
   let second = yield first + 2;
   yield sencond + 4;
   yield 5;
}
let sum = create();
console.log(sum.next()) // {value: 1, done: false}
console.log(sum.next(4)) // {value: 6, dond: false}
console.log(sum.throw(new Error("err"))); // 从生成器中抛出了错,后续done值为true

内置的迭代器
ES6中包含数组、Map、Set三种集合对象类型,这三种类型都拥有三种迭代器。
1、entries():返回一个包含键值对的迭代器
2、values():返回一个包含集合中的值的迭代器
3、keys():返回一个包含集合中键的迭代器
上面提到了for-of和迭代器是协同工作的,在使用for-of时values()方法是数组和Set的默认迭代器,entries()方法是Map的默认迭代器
例子:

let colors = ['red', 'green', 'blue'];
let track = new Set(['123', '224',  '412'])
let data = new Map()
data.set("name", "digua")
data.set("age", 12)
for (let value of colors.entries()) {
    console.log(value)
}
//[ 0, "red"] [1, "green"] [2, "blue"] 
// 默认情况下为values()
for (let value of colors) {
    console.log(value)
}
// "red" "green" "blue"
for (let value of track.entries()) {
    console.log(value)
}
// ["123", "123"] ["234", "234"] ["412", "412"]
// 默认情况下为values()
for (let value of track) {
    console.log(value)
}
// "123" "234" "412"
for (let value of data.entries()) {
    console.log(value)
}
//["name": "digua"]  ["age", 12]
// 默认情况下为entries()
for (let value of data) {
    console.log(value)
}
//["name": "digua"]  ["age", 12]

扩展运算符与可迭代对象
之前提到扩展运算符中运用了迭代器,它会使用默认迭代器来判断需要使用哪些值,将所有值从迭代器取出插入数组。
例子

// set
let set = new Set([1, 2, 2, 3, 4])
let arr = [...set]
console.log(arr) // [1, 2, 3, 4]
// map
let map = new Map(["name", "digua"],["age", 20])
let arr1 = [...map]
console.log(arr1) // [["name", "digua"], [["age", 20]] 

异步任务
迭代器对异步任务的意义在于,我们可以通过一个看似同步的代码来实现异步操作。下面写一段伪代码来说明迭代器实现的一个异步操作

function* getname() {
    let  res = yield read('name');
    dosomething(res)
}

例子中dosomething的操作是在等read操作执行之后,那么这时就实现一个异步操作。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值