循环语句的迭代器可以极大简便的简化数据操作,,例如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种对象
跳过吧,这东西看来无用。
给迭代器传递参数,给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不支持面向对象,所以class语法糖应劫而生。
尽管类与自定义类型之间有诸多相似之处,我们仍然需要牢记他们的这些差异:
以下是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就是代表的扩展的类 extends class 在es6的时候没有静态属性,只有静态方法,但是在es7中却可以这样定义静态属性。非常神奇。。。