Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

深入理解ES6 - Nicholas C.Zakas(二) #51

Open
plh97 opened this issue May 9, 2018 · 0 comments
Open

深入理解ES6 - Nicholas C.Zakas(二) #51

plh97 opened this issue May 9, 2018 · 0 comments
Assignees
Labels
博客 写一些前端技术记录 学习 如果不学习,那今天和昨天又有什么区别 看书 其实如果不看书的话,那么每天写的东西都和昨天一样,又有什么意思

Comments

@plh97
Copy link
Owner

plh97 commented May 9, 2018

经典继续阅读,虽然好像越来越没动力去读了。

第八章 迭代器Iterator 和生成器Generator

循环语句的迭代器可以极大简便的简化数据操作,,例如for...in循环,...扩展符,甚至异步编程都是运用的迭代器。
也许你写过for循环

for (let index = 0; index < array.length; index++) {
  const element = array[index];
}

是不是很麻烦,迭代器随之诞生,它是为专门为迭代过程设计的接口,所有的迭代器对象都有一个next()方法,每次调用这个都返回一个结果对象,

{
  value:"下一个要返回的值", 
  done: "true/false"
}

为了深入了解迭代器,我们打算手写一个迭代器函数

function createIterator (items){
  var i = 0;
  return {
    next: function (){
      var done = (i >= items.length);
      var value = !done ? items[i++] : undefined;
      return { done,value }
    }
  }
}
var iterator = createIterator([1,2,3,4,5]);
console.log(iterator.next());  // {done: false, value: 1}
console.log(iterator.next());  // {done: false, value: 2}
console.log(iterator.next());  // {done: false, value: 3}
console.log(iterator.next());  // {done: false, value: 4}
console.log(iterator.next());  // {done: false, value: 5}
console.log(iterator.next());  // {done: true, value: undefined}
console.log(iterator.next());  // {done: true, value: undefined}
console.log(iterator.next());  // {done: true, value: undefined}

上面通过闭包原理简单实现了一个迭代器,迭代器内置next()方法,其实就是返回的对象有next()方法,以及一个私有变量i,他会自增。

function *createIterator(items) {
  items.forEach(arr=>{
    yield items[i]
  })
}
let iterator = createIterator([1,2,3]);
console.log(iterator.next());
function *createIterator(items) {
  for (let i = 0; i < items.length; i++) {
    yield items[i]
  }
}
let iterator = createIterator([1,2,3]);
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());
console.log(iterator.next());

同样的道理,迭代器关键字,yield不能在其他函数内部使用,即便是箭头函数这种伪函数同样不行,

内建迭代器

es6中3种类型的集合对象,数组,map集合,set集合,他们都有以下3种对象

  • extries() 返回一个迭代器,其值为多个键值对。
  • values() 返回一个迭代器,其值为集合的值。
  • keys() 返回一个迭代器,其值为集合种的所有键名,

跳过吧,这东西看来无用。

高级迭代功能

给迭代器传递参数,给next方法传递参数,这个参数会成为上一个yield语句的返回值,

function *createIterator(){
  let first = yield 1;
  let second = yield first + 2;
  yield second + 3;
}
let iterator = createIterator();
console.log(iterator.next());      // {value: 1, done: false}
console.log(iterator.next(4));    // {value: 6, done: false}
console.log(iterator.next(5));    // {value: 8, done: false}
console.log(iterator.next());      // {value: undefined, done: true}

第一次调用next方法,无论传什么参数都会被丢弃。由于传给next()方法会代替上一次yield返回值,

异步执行任务

不如async+promise语法糖好用

JavaScript 中的类

JavaScript不支持面向对象,所以class语法糖应劫而生。

为何适用类

尽管类与自定义类型之间有诸多相似之处,我们仍然需要牢记他们的这些差异:

  • 函数声明可以被提升,而class不能被提升,真正执行声明语句之前,他们会一直存在于临时死区。
  • 类型声明中所有的代码将自动允许在严格模式,而且无法让其脱离严格模式。
由此可见,严格模式是大势所趋,后续代码默认适用严格模式
  • 在自定义类型中,需要通过Object.defineProperty()方法手工指定某个方法不可枚举,,而在类中,所有方法都不可枚举。
  • 每个类中都有[[Construct]]的内部方法,通过关键字new调用。
  • 适用关键字new以外的方式,调用类的构造函数会导致程序抛出错误。
  • 在类中,修改类名会报错。

以下是class语法糖的原生写法

let PersonType2 = (function (){
  "use strict";
  const PersonType2 = function (name){
    if(typeof new.target === 'undefined'){
      throw new Error('必须通过new 关键字调用');
    }
    this.name = name;
  }
  Object.defineProperty(PersonType2, "sayName", {
    value: function (){
      // 确保不会通过关键字new 调用方法
      if (typeof new.target !== "undefined") {
        throw new Error('不能通过 new 关键字调用');
      }
      console.log(this.name);
    },
    enumerable: false,
    writable: true,
    configurable: true,
  })
  return PersonType2;
}())

类class名字可以在外部修改,但是不能在内部修改。类是一等公民。

静态成员

在ECMAscript5或者早期版本,直接将方法添加到构造函数中模拟静态成员是一种常见的形态。例如:

function PersonType(name){
  this.name = name;
}
// 静态方法
PersonType.create = function(name){
  return new PersonType(name);
}
// 实例方法
PersonType.prototype.sayname = function(){
  console.log(this.name)
}
var person = PersonType.create('Nicholas')

下面是等价代码es6版本

class PersonClass {
  constructor(name) {
    this.name = name;
  }
  sayname(){
      console.log(this.name)
  }
  static create(){
      return new PersonClass(name);
  }
}

关于super,

super就是代表的扩展的类 extends
class 在es6的时候没有静态属性,只有静态方法,但是在es7中却可以这样定义静态属性。非常神奇。。。

@plh97 plh97 added 学习 如果不学习,那今天和昨天又有什么区别 博客 写一些前端技术记录 看书 其实如果不看书的话,那么每天写的东西都和昨天一样,又有什么意思 挖坑 待填写的坑 labels May 9, 2018
@plh97 plh97 self-assigned this May 9, 2018
@plh97 plh97 removed the 挖坑 待填写的坑 label May 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
博客 写一些前端技术记录 学习 如果不学习,那今天和昨天又有什么区别 看书 其实如果不看书的话,那么每天写的东西都和昨天一样,又有什么意思
Projects
None yet
Development

No branches or pull requests

1 participant