JavaScript 迭代器(Iterator)和生成器(Generator)

你不知道的JavaScript-----生成器 生成器是一个新的函数类型,可以通过yield语句暂停自身,它的暂停和恢复是合作式的而不是抢占式的。yeild和next()除了可以控制流程的暂停和结束,还能进行双向消息传递。在异步流程控制方面,生成器的优点在于可以以同步的、顺序的方式表达异步逻辑,提高了代码可读性。 阅读详情

说起迭代,或许大多数人想到的就是循环,但是迭代和循环并不是等价的,循环是迭代机制的基础。那么什么是迭代呢?个人理解的是按照顺序重复多次执行同一段程序,通常会有明确的中止条件。
在ECMAScript 6规范中新增了两个高级特性:迭代器和生成器,将迭代的概念直接带入核心语言,并提供了一种机制来自定义for...of循环的行为。
本文就来探寻一下这两个新特性。

一、迭代协议

迭代协议具体分为可迭代协议和迭代器协议。

1.1 可迭代协议

(1)什么是可迭代协议

可迭代协议允许 JavaScript 对象定义或定制它们的迭代行为。

(2)成为可迭代对象的条件

一个对象要成为可迭代对象,必须实现@@iterator方法,即对象(或者原型链上的某个对象)必须有一个键为 @@iterator 的属性,可通过常量 Symbol.iterator访问该属性。所以:

一个对象成为可迭代对象的条件:实现了@@iterator方法

[Symbol.iterator]: 一个无参数的函数,其返回值为一个符合迭代器协议的对象。

(3)相关说明

  • 当一个对象需要被迭代的时候,会首先不带参数调用其@@iterator方法,然后使用此方法返回的迭代器获得要迭代的值。
  • @@iterator方法是被当作可迭代对象的方法进行调用的,其函数内部的this值指向可迭代对象。
  • 此函数可以是普通函数,也可以是生成器函数
  • 实际写代码时,不需要显示调用@@iterator方法来生成迭代器。以下这些接收可迭代对象的原生语言特性会在后台调用提供的可迭代对象的@@iterator方法来创建一个迭代器。
    • for-of 循环
    • 数组解构
    • 扩展操作符
    • Array.from()
    • 创建集合
    • 创建映射
    • Promise.all() 接收由promise组成的可迭代对象
    • promise.race() 接收由promise组成的可迭代对象
    • yield*操作符,在生成器中使用

1.2 迭代器协议

(1)什么是迭代器协议

迭代器协议定义了产生一系列值(无论是有限个还是无限个)的标准方式。当值为有限个时,所有的值都被迭代完毕后,则会返回一个默认返回值。

(2)成为迭代器的条件

一个对象成为迭代器的条件:实现了一个拥有以下语义(semantic)的next()方法

next: 一个无参数的或者可以接受一个参数的函数,返回一个应当拥有以下两个属性的对象:

  • done(boolean):
    • 如果迭代器可以产生序列中的下一个值,则为 false。(这等价于没有指定 done 这个属性。)
    • 如果迭代器已将序列迭代完毕,则为 true。这种情况下,value 是可选的,如果它依然存在,即为迭代结束之后的默认返回值。
  • value:迭代器返回的任何 JavaScript 值。done 为 true 时可省略。
    • next() 方法必须返回一个对象,该对象应当有两个属性: done 和 value
    • 如果返回了一个非对象值(比如 false 或 undefined),则会抛出一个 TypeError 异常(“iterator.next() returned a non-object value”)。

如下代码中的对象同时满足可迭代协议和迭代器协议:

var myIterator = {
    // 实现了next方法
    next: function() {
        // ...
    },
    
    // 实现了 @@iterator 方法
    [Symbol.iterator]: function() { return this }
} 

二、迭代器(iterator)

2.1 什么是迭代器

在JavaScript中,迭代器是一个对象,它定义一个序列,并在中止时可能返回一个返回值。具体来说,迭代器是通过使用next()方法实现迭代器协议的任何一个对象。

此外,迭代器是按需创建的一次性对象。每个迭代器都会关联一个可迭代对象,而迭代器会暴露迭代其关联可迭代对象的API。迭代器无需了解与其关联的可迭代对象的结构,只需要知道如何取得连续的值。

一旦创建,迭代器对象可以通过重复调用next()显式地迭代。 迭代一个迭代器被称为消耗了这个迭代器,因为它通常只能执行一次。 在产生终止值之后,对next()的额外调用应该继续返回{done:true}。

以内置可迭代对象数组(Array)的为例,其内部包含[Symbol.iterator]属性,调用@@iterator方法则会生成一个迭代器,然后通过迭代器的next()消耗迭代器:

let arr = [1, 3, 6];
iter = arr[Symbol.iterator]();  
console.log(iter);  // Array Iterator {}

console.log(iter.next());  // {value: 1, done: false}
console.log(iter.next());  // {value: 3, done: false}
console.log(iter.next());  // {value: 6, done: false}
console.log(iter.next());  // {value: undefined, done: true} 

2.2 自定义迭代器

如上所述,成为可迭代对象需要实现@@iterator方法,成为迭代器对象需要实现next()方法。所以,一般自定义迭代器可写成如下形式。

class Counter {
    constructor(limit) {
        this.limit = limit;
    }

    // 实现了[Symbol.iterator] 方法,Counter满足成为可迭代对象的条件
    [Symbol.iterator]() {
        let count = 1, limit = this.limit;
        return {
            // 实现了 next 方法,满足成为迭代器的条件,则该[Symbol.iterator]方法的返回值是一个迭代器
            next() {
                if (count <= limit) {
                    // 返回值包含 done 和 value 两个属性
                    return {done: false, value: count++};
                } else {
                    return {done: true, value: undefined};
                }
            }
        };
    }
}

let count = new Counter(3);
for (let i of count) {
    console.log(i);  // 1 2 3
} 

某些迭代器对象内部也实现了@@iterator方法,且会返回相同的迭代器。

let arr = [1, 2]
let iter1 = arr[Symbol.iterator]();
let iter2 = iter1[Symbol.iterator]();
console.log(iter1 === iter2) 

2.3 提前终止迭代器

迭代器中可选的 return() 方法用于指定在迭代器提前关闭时执行的逻辑。

导致迭代器提前关闭的情况包括:

  • for-of循环通过 break、continue、return或者throw提前退出。
  • 解构操作未消费所有的值。
class Counter {
    constructor(limit) {
        this.limit = limit;
    }

    // 实现了[Symbol.iterator] 方法,Counter满足成为可迭代对象的条件
    [Symbol.iterator]() {
        let count = 1, limit = this.limit;
        return {
            // 实现了 next 方法,满足成为迭代器的条件,则该[Symbol.iterator]方法的返回值是一个迭代器
            next() {
                if (count <= limit) {
                    // 返回值包含 done 和 value 两个属性
                    return {done: false, value: count++};
                } else {
                    return {done: true, value: undefined};
                }
            },
            // 迭代器提前关闭执行的操作
            return() {
                console.log('提前关闭!');
                return {done: true};
            }
        };
    }
}

let count = new Counter(3);
for (let i of count) {
    if (i > 1)   
        break;  
    console.log(i);  
}
// 1
// 提前关闭! 

但是需要注意的是,有些迭代器是不可关闭的(可通过检测迭代器实例的return属性是不是一个函数来判定),对一个不可关闭的迭代器添加return属性并不会让其变为可关闭的。例如,数组迭代器是不可关闭的。

let arr = [1, 2, 3];
let iter = arr[Symbol.iterator]();
iter.return = function(){
    console.log('提前关闭!');
    return {done: true};
}

for (let i of iter) {
    if (i > 1)   
        break;  
    console.log(i);  
}
// 1
// 提前关闭!

for (let i of iter) {
    console.log(i);  
}
// 3 

三、生成器(generator)

自定义的迭代器是一个有用的工具,但是由于需要显示地维护其内部状态,因此需要谨慎地创建, 对此ES6提供了生成器结构。在介绍生成器函数如何使用之前,我们先介绍一些生成器相关的基础知识。

3.1 生成器对象(Generator)

生成器对象是由一个生成器函数返回的迭代器,并且符合可迭代协议和迭代器协议。

Generator的原型上包含以下三种方法:

(1)Generator.prototype.next()

next() 方法返回一个包含属性 done 和 value 的对象。该方法也可以通过接受一个参数用以向生成器传值。

语法:

gen.next(value) 
  • value:可选,向生成器传递的值.(如果传递了该参数,那么这个参数会传给上一条执行的 yield语句左边的变量)
  • 返回值:返回的对象包含两个属性:
    • done (布尔类型)
      • 如果迭代器超过迭代序列的末尾,则值为 true。 在这种情况下,value可选地指定迭代器的返回值。
      • 如果迭代器能够生成序列中的下一个值,则值为false。 这相当于没有完全指定done属性。
    • value 迭代器返回的任意的Javascript值。当 done 的值为 true 时可以忽略该值。
function* generator() {
    let a = yield 1;
    let b = yield 2;
    let c = yield 3;
    console.log(`a = ${a}, b = ${b}, c = ${c}`)
}

let gen = generator(); // "Generator { }"
console.log(gen.next(10));  // {value: 1, done: false}
console.log(gen.next(9));  // {value: 2, done: false}
console.log(gen.next());  // {value: 3, done: false}
console.log(gen.next(8));  
// a = 9, b = undefined, c = 8
// {value: undefined, done: true} 

从上述代码可以看出:

  • next()的参数会传给上一条执行的 yield语句左边的变量。 所以,第一次调用gen.next(10),参数10并没有传递给任何变量。
  • 第二次调用gen.next(9)时,参数 9 传递给了上一条执行的 yield语句左边的变量 a
  • 第三次调用gen.next()时,没有传递参数,所以变量 b 的值为undefined
  • 第四次调用gen.next(8)时,虽然返回值中done: true,但也不影响参数的传递
  • 此外,next()函数的返回值,与传递的参数无关,只与yield右边返回的值以及生成器是否结束有关。

(2)Generator.prototype.return()

return() 方法返回给定的值并结束生成器。

语法:

gen.return(value) 
  • value: 需要返回的值
  • 返回值:返回该函数参数中给定的值.

具体示例见3.3.2

(3)Generator.prototype.throw()

throw() 方法用来向生成器抛出异常,并恢复生成器的执行,返回带有 done 及 value 两个属性的对象。

语法:

gen.throw(exception) 
  • exception:用于抛出的异常。 使用 `Error的实例对调试非常有帮助.
  • 返回值:带有两个属性的`对象
    • done (boolean)
      • 如果迭代器已经返回了迭代序列的末尾,则值为 true。在这种情况下,可以指定迭代器 value 的返回值。
      • 如果迭代能够继续生产在序列中的下一个值,则值为 false。 这相当与不指定 done 属性的值。
    • value - 迭代器返回的任何 JavaScript 值。当 done 是 true 的时候可以省略。
function* gen() {
    while(true) {
      try {
         yield 42;
      } catch(e) {
        console.log("Error caught!");
      }
    }
  }
  
  var g = gen();
  console.log(g.next()); // { value: 42, done: false }
  console.log(g.throw(new Error("Something went wrong"))); // "Error caught!"  { value: 42, done: false }
  console.log(g.next()); // { value: 42, done: false } 

从上述代码中可以看出,关于throw()方法需要注意的是,throw()方法并不会结束生成器\color{red}{不会结束生成器}不会结束生成器。

3.2 yield 关键字 和 yield* 表达式

(1)yield 关键字

yield 关键字用来暂停和恢复一个生成器函数

语法:

[rv] = yield [expression]; 
  • expression: 定义通过迭代器协议从生成器函数返回的值。如果省略,则返回undefined。
  • rv:返回传递给生成器的next()方法的可选值,以恢复其执行

yield关键字使生成器函数执行暂停,yield关键字后面的表达式的值返回给生成器的调用者。它可以被认为是一个基于生成器的版本的return关键字。

yield关键字实际返回一个IteratorResult对象,它有两个属性,value和done。value属性是对yield表达式求值的结果,而done是false,表示生成器函数尚未完全完成。

(2)yield* 表达式

yield* 表达式用于委托给另一个generator 或可迭代对象。

语法:

yield* [[expression]]; 

expression:返回一个可迭代对象的表达式。

  • yield*委托给其他生成器:
function* generator(){
    yield* anotherGenerator();
}
function* anotherGenerator(){
    yield 1
}

var gen = generator();
console.log(gen.next()); // {value: 1, done: false}
console.log(gen.next()); // {value: undefined, done: true} 
  • yield*委托给其他可迭代对象:
function* generator(){
    yield* [1, 2];
}

var gen = generator();
console.log(gen.next()); // {value: 1, done: false}
console.log(gen.next()); // {value: 1, done: false}
console.log(gen.next()); // {value: undefined, done: true} 
  • yield* 表达式迭代操作数,并产生它返回的每个值。
  • yield* 表达式本身的值是当迭代器关闭时返回的值(即done为true时)。
function* anotherGenerator() {
    yield 1
    return "foo";
}
  
var result;

function* generator() {
    result = yield* anotherGenerator();
}

var iterator = generator();

console.log(iterator.next()); // { value: 1, done: false }
console.log(iterator.next()); // {value: undefined, done: true}

console.log(result);  // "foo"
// 若anotherGenerator函数没有显示返回 "foo",那么result的值为undefined 

3.3 生成器函数

生成器函数允许定义一个包含自由迭代算法的函数,同时可以自动维护自己地状态。生成器函数在执行时能暂停,后面又能从暂停处继续执行。

3.3.1定义生成器函数

在JavaScript中可以通过生成器函数声明、生成器函数表达式、GeneratorFunction构造函数来定义生成器函数

(1) function*

function* 这种声明方式(function关键字后跟一个星号)会定义一个**生成器函数 (** generator function ) ,它返回一个 Generator 对象。

function* name([param[, param[, ... param]]]) { statements } 
  • name:函数名
  • param:要传递给函数的一个参数的名称,一个函数最多可以有255个参数。

可通过以下方式在不同地方定义生成器函数。

// 生成器函数声明
function* generatorFn() {}

// 生成器函数表达式
let generatorFn = function* () {}

// 作为对象属字面量方法地生成器函数
let obj = {
    * generatorFn() {}
}

// 作为类实例方法的生成器函数
class Foo = {
    * generatorFn() {}
} 
(2)GeneratorFunction

除了通过生成器函数声明和生成器函数表达式来定义生成器函数,也可以通过GeneratorFunction构造其创建新的生成器函数对象。在JavaScript中,生成器函数实际上都是GeneratorFunction的实例对象。

new GeneratorFunction ([arg1[, arg2[, ...argN]],] functionBody) 
  • arg1, arg2, ... argN:函数使用的名称作为形式参数名称。每个必须是一个字符串,对应于一个有效的JavaScript标识符或这样的字符串的列表,用逗号分隔;如“x”,“theValue”或“a,b”。
  • functionBody:一个包含多条表示JavaScript函数体语句的字符串。

GeneratorFunction不是全局对象
GeneratorFunction不是全局对象,需要通过Object.getPrototypeOf(function*(){}).constructor获取

// 获取 GeneratorFunction 对象
GeneratorFunction = Object.getPrototypeOf(function*(){}).constructor;

// 通过 GeneratorFunction 构造器创建生成器函数
generatorFn = new GeneratorFunction();
console.log(generatorFn);  // ƒ* anonymous() { } 

所有生成器函数都是 GeneratorFunction 的实例对象

function* generatorFn() {}
GeneratorFunction = Object.getPrototypeOf(function*(){}).constructor;

console.log(generatorFn instanceof GeneratorFunction)  // true
console.log(generatorFn.__proto__ === GeneratorFunction.prototype)  // true 

注意:这种生成生成器函数的方式不推荐使用

3.3.2 执行生成器函数

(1)生成器函数一般执行过程

调用一个生成器函数:

  • 首先并不会马上执行它里面的语句,而是返回一种称为Generator的 迭代器 (iterator)对象。
  • 当这个迭代器的 next() 方法被首次(后续)调用时,其内的语句会执行到第一个(后续)出现yield的位置为止,yield 后紧跟迭代器要返回的值。
  • 或者如果用的是 yield*(多了个星号),则表示将执行权移交给另一个生成器函数(当前生成器暂停执行),继续执行到另一个生成器函数出现yield的位置为止。
// 生成器函数
function* anotherGenerator() {
    yield 2;
    yield 3;
}

function* generator() {
    yield 1;
    yield* anotherGenerator();
    yield 4;
}

// 调用生成器函数首先返回一个Generator 
let gen = generator(); // "Generator { }"

// 首次调用 generator 的 next() 方法,执行到第一个yield出现的位置为止,并返回yield后的值
console.log(gen.next());  // {value: 1, done: false}

// 接着调用 generator 的 next() 方法,遇到 yield* ,将执行权移交给 anotherGenerator
// 继续执行到 anotherGenerator 出现 yield 的位置,并返回yield后的值
console.log(gen.next());  // {value: 2, done: false}

// 接着调用 generator 的 next() 方法,anotherGenerator 执行到出现 yield 的位置,并返回yield后的值
console.log(gen.next());  // {value: 3, done: false}

// 接着调用 generator 的 next() 方法,anotherGenerator 生成器函数已经执行完毕,执行权交回 generator
// 继续执行到 generator 出现 yield 的位置,并返回yield后的值
console.log(gen.next());  // {value: 4, done: false}

// generator 生成器函数执行完毕,next() 返回值中 done 为 true
console.log(gen.next());  // {value: undefined, done: true} 

上述执行过程如下:

未命名文件.png

(2)带参数的生成器函数

生成器也可以接收参数

function* generator(n){
    yield n + 2;
}

var gen = generator(2);
console.log(gen.next().value); // 4
console.log(gen.next().value); // undefined 
(3)生成器 暂停 或 结束 执行的条件

每次调用生成器的next()方法时,生成器都会恢复执行,直到达到以下某个值:

  • yield

导致生成器再次暂停并返回生成器的新值。 下一次调用next()时,在yield之后紧接着的语句继续执行。

  • 到达生成器函数的结尾

在这种情况下,生成器的执行结束,并且IteratorResult给调用者返回undefined并且done为true。

function* generator() {
    yield 1;
    yield 2;
}

let gen = generator(); // "Generator { }"
// 遇到 yield 暂停并返回生成器的新值
console.log(gen.next());  // {value: 1, done: false}
console.log(gen.next());  // {value: 2, done: false}

// 到达生成器函数的结尾, 生成器的执行结束
console.log(gen.next());  // {value: undefined, done: true} 
  • 到达return 语句

在这种情况下,生成器的执行结束,并将IteratorResult返回给调用者,其值是由return语句指定的,并且done 为true。

function* generator() {
    yield 1;
    return 2;
    yield 3;
}

let gen = generator(); // "Generator { }"
console.log(gen.next());  // {value: 1, done: false}

// 到达return语句,生成器结束
console.log(gen.next());  // {value: 2, done: true}
console.log(gen.next());  // {value: undefined, done: true} 
  • throw

用于从生成器中抛出异常。这让生成器完全停止执行,并在调用者中继续执行,正如通常情况下抛出异常一样。

function* generator() {
    yield 1;
    throw new Error();
    yield 3;
}

let gen = generator(); // "Generator { }"
console.log(gen.next());  // {value: 1, done: false}
console.log(gen.next());  // Uncaught Error
console.log(gen.next());  // 该条语句不会继续执行了 
(4)提前终止生成器

3.1 中提到,Generator对象上有个方法return()可以结束生成器,具体使用如下:

function* gen() {
    yield 1;
    yield 2;
    yield 3;
  }
  
  var g = gen();
  
  console.log(g.next());        // { value: 1, done: false }
  
  // 提前结束生成器
  console.log(g.return("foo")); // { value: "foo", done: true }
  
  // 生成器已结束,后续值无法迭代
  console.log(g.next());        // { value: undefined, done: true } 

此外,对于已经结束的生成器对象使用return()方法,如果提供了参数,则参数将被设置为返回对象的value属性的值。

function* gen() {
    yield 1;
  }
  
  var g = gen();
  
  console.log(g.next());        // { value: 1, done: false }
  console.log(g.next());        // { value: undefined, done: true }
  console.log(g.return("foo")); // { value: "foo", done: true } 

四、for-of

说到迭代器和生成器,那就顺带了解以下 for-of

for...of语句在可迭代对象上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句

语法

for (variable of iterable) {
    //statements
} 
  • variable: 在每次迭代中,将不同属性的值分配给变量。
  • iterable:被迭代枚举其属性的对象。

for...of与for...in的区别

无论是for...in还是for...of语句都是迭代一些东西。它们之间的主要区别在于它们的迭代方式。

  • for...in 语句以任意顺序迭代对象的可枚举属性。
  • for...of 语句遍历可迭代对象定义要迭代的数据。
let arr = ['a', 'b'];

for (let i in arr) {
    console.log(i);  
}
// 0
// 1

for (let i of arr) {
    console.log(i);  
}
// a
// b 

arr 的所有属性描述如下,可迭代属性有’0’, ‘1’ image.png

五、小结

  • 什么是可迭代对象:实现@@iterator方法的对象,可通过常量 Symbol.iterator访问该属性
  • 什么是迭代器:本质上就是一个对象,且实现了一个拥有特定语义的next()方法
  • 可以通过自定义@@iterator方法和next()方法自定义迭代器,并且可通过return()方法提前终止迭代器。
  • 什么是生成器:一个拥有在函数块内暂停和恢复代码执行能力的结构。通过next()恢复代码执行,遇到yield关键字暂停执行。
  • 生成器执行过程中遇到throw和return会结束生成器,也可以调用生成器对象的return()函数提前结束生成器

本文到此就结束啦,有错误希望大佬们提出指正呀!

全网最完整的JavaScript迭代器(遍历器)整理长文,强烈建议收藏!!! 全网最完整的JavaScript迭代器(遍历器)整理长文. Iterator,for...in,for...of,for await... of,forEach(),map(),every(),some(),find(),findIndex(),filter(),reduce(),reduceRight() 迭代器模式是指提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。 for...of不能遍历object对象 阅读详情

相关推荐

JavaScript 中的迭代器、生成器与可迭代对象:深入理解遍历机制

迭代器是一个对象,它提供了一种标准的方式来遍历集合中的元素。迭代器对象必须实现一个next()value:当前遍历的值。done:一个布尔值,表示遍历是否结束。} else {// 输出: 1, 2, 3, 4, 5myIterable是一个可迭代对象,因为它实现了方法。方法返回一个迭代器对象,该对象实现了next()方法。next()方法每次返回一个值,直到遍历结束。生成器是一种特殊的函数,通过function*关键字定义。

vvilkin的学习备忘 1473

JS的迭代器

在JavaScript中,迭代器(Iterator)是一种遍历任何可迭代对象(Iterable)的通用接口。迭代器是ES6规范中引入的一种新的数据类型,用于遍历各种数据结构,包括数组、对象、Map、Set等。在语言层面上,迭代器可以被看做一个有next方法的对象,每次调用next方法都可以返回一个值对象(Value)和一个布尔值(Done),表示是否遍历结束。其中,Value代表当前迭代项的取值,Done代表迭代是否结束。

一步一个脚印,踏实努力,向着目标前进 3648

「JS 基础」迭代器和生成器 Iterator & Generator 入门

JavaScript的生成器(Generators)和迭代器(Iterators)是ES6引入的功能,使得开发者可以更方便地实现自定义的迭代逻辑。在创建自定义数据结构时,你可能需要提供一种遍历结构中元素的方法。迭代器和生成器允许你定义数据结构的迭代逻辑,使其能够使用标准的迭代协议进行遍历。实现一个自定义集合类(如图、树等),并通过生成器为其提供自定义的遍历逻辑。

Constantiny的博客 607

JS - iterator(迭代器)

这样就有了四种数据集合,用户还可以组合使用它们,定义自己的数据结构,比如数组的成员是Map,Map的成员是对象。这个对象有 value 和 done 两个属性,value属性返回当前位置的成员,done属性是一个布尔值,表示遍历是否结束,即是否有必要再调用一次next ()。其次,Set结构遍历时,返回的是一个值。而Map结构遍历时,返回的是一个数组,该数组的两个成员分别是当前Map成员的键名和键值。实际上,这提供了一种简便机制,可以将任何部署了 Iterator 接口的数据结构,转为数组。

m0_52545254的博客 6855

gem5 prefetcher

最近在gem5上做预取实验,添加自己的预取算法,这里采用hardware stream prefetcher , 修改了几个bug才给实验调试通过,发文记录下实验过程。 gem5上添加自己的预取算法步骤: (1)路径gem5-master/configs/common/Caches.py下,开启预取:class L1Cache(Cache): assoc = 2 tag_late

编程邦 3845

台达PLC DIAdesigner-AX 编程笔记

1、登陆台达思图软件网站,选择Download,登陆注册好的账号,下载DIAInstaller,下载后安装(安装目录不要修改);

weixin_45823621的博客 6676

web前端高级JavaScript - JavaScript中的迭代器Iterator和生成器Generator

迭代器Iterator 迭代器(遍历器)Iterator是ES6中新增的一套语法规范,但在ES6中并没有Iterator这个类。 迭代器(Iterator)是一种机制(接口):为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署Iterator接口,就可以完成遍历操作,依次处理该数据结构的所有成员。 迭代器的特点: 拥有next方法用于一次遍历/迭代数据结构的成员 每次遍历返回的结果是一个对象 {done: false, value:xxx} done记录是否遍历完成 value:当前遍历的结

lixiaosenlin的专栏 5957

整车 EOL下线 测试系统介绍

整车下线(EOL)测试专门针对整车进行设计开发,是车企将组装好的整车交付客户前的 最后一道检测工序。EOL 测试针对的是整车下线测试,不同于零部件下线,是整车级别的下线 测试,测试过程关系整车的每个零部件,其测试质量直接影响到整车的质量好坏。因此,整车EOL测试是整车下线必不可少的测试过程.

王小奎的博客 5487

js迭代器Iterator和生成器Generator深入理解

什么是迭代器 迭代器是一种特殊对象,它具有一些专门为迭代过程设计的专有接口,所有的迭代器对象都有一个next()方法,每次调用都返回一个结果对象,结果对象有两个属性:一个是value,表示下一个将要返回的值,另一个是done,它是一个布尔类型的值,当没有更多可返回数据时返回true。迭代器会保存一个内部指针,用来指向当前集合中值的位置,每调用一次next()方法,都会返回下一个可用值。 如果在最后一个值返回后再调用next()方法,那么返回的对象中属性done的值为true,属性value则包涵迭代器最

li_Ryan的博客 561

Java开发者必看:WPS Office在线预览接入实战(含回调配置避坑指南)

本文为Java开发者提供了WPS Office在线预览功能的完整接入实战指南。详细解析了从服务申请、生成带签名的访问URL,到实现核心回调接口(文件信息、用户信息、文件保存)的全流程,并重点分享了签名算法与回调配置中的关键避坑点,帮助开发者高效集成,提升Web应用文档处理体验。

vodka的博客 1328

南大计算机2024保研笔试:编译原理等5门专业课考点分布与408复习避坑指南

本文详细解析了南京大学计算机2024保研笔试的考点分布与复习策略,重点突出编译原理(占比28%-32%)和离散数学的特色考核。提供跨课程复习方法、真题题型分析及高效备考建议,帮助考生突破传统408框架,应对南大独特的命题风格。

weixin_29304985的博客 345

JS高级——Iterator迭代器、Generator生成器

一、什么是迭代器? 在JavaScript中,迭代器也是一个具体的对象,这个对象需要符合迭代器协议(iterator protocol): 迭代器协议定义了产生一系列值(无论是有限还是无限个)的标准方式; 那么在js中这个标准就是一个特定的next方法; next方法有如下的要求: 一个无参数或者一个参数的函数,返回一个应当拥有以下两个属性的对象: done:(boolean) 如果迭代器可以产生序列中的下一个值,则为 false。(这等价于没有指定 done 这个属性。) 如果迭代器已将序列迭代完毕

zep 1473

嵌入式开发实战:如何用cJSON库在STM32上实现轻量级JSON通信(附完整代码)

本文详细介绍了如何在STM32嵌入式系统中使用cJSON库实现高效的JSON通信方案。针对嵌入式环境的内存限制,提供了内存优化策略、cJSON库的深度定制方法以及完整的通信流程实现代码,帮助开发者解决JSON解析效率低下和跨平台兼容性等核心挑战。

star5的专栏 471

iterator和generator

iterator和generator

betterangela的博客 134

基于Matlab模拟六自由度Stewart并联机器人运动学逆解

在现代工业和科学领域中,机器人技术的发展已经取得了巨大的进步,为生产和研究提供了许多便利。其中,六自由度Stewart并联机器人是一种广泛应用于各种领域的机器人系统。它具有高精度、高刚度和高可靠性的特点,被广泛应用于飞行模拟器、手术机器人和运动仿真等领域。然而,要使Stewart并联机器人能够实现复杂的运动任务,我们需要了解其运动学逆解。运动学逆解是指根据机器人末端执行器的位置和姿态,计算出各个关节的角度和长度。这对于控制机器人的运动非常重要,因为它可以帮助我们确定机器人各个关节的运动范围和工作空间。

qq_59747472的博客 1127

手把手教你ensp仿真搭建校园网(含防火墙及无线网络)系列(一)校园网核心交换机配置

本系列博客将带你从零开始,使用 华为 eNSP(Enterprise Network Simulation Platform) 仿真搭建一个完整的校园网络,涵盖 核心层、汇聚层、接入层、防火墙安全策略、无线AC+AP组网 等实战场景。无论你是网络初学者还是希望深化实战经验的工程师,都能通过本教程掌握企业级网络的规划、配置与排错技巧。

echo的博客 3797

JS迭代器Iterator及生成器Generator

JS迭代器Iterator及生成器Generator

qq_23355915的博客 289

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

JS中的迭代器(iterator)和生成器(generator)

迭代器 迭代器是一个对象,是确使用户可在容器对象(container,例如链表或数组)上遍访的对象,使用该接口无需关心对象的内部实现细节。 next方法有如下的要求: 一个无参数或者一个参数的函数,返回一个应当拥有以下两个属性的对象: done(boolean) ü 如果迭代器可以产生序列中的下一个值,则为 false。(这等价于没有指定 done 这个属性。)如果迭代器已将序列迭代完毕,则为 true。这种情况下,value 是可选的,如果它依然存在,即为迭代结束之后的默认返回值。 value 迭代器返

weixin_44416058的博客 5227

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

JS高级 迭代器-生成器:Iterator-Generator

写一个针对数组的初级迭代器在函数里面定义了一个iterator对象,里面有next方法,返回值是一个包含done与value的对象,这就是一个迭代器。

qq_54517101的博客 430

14 js高级 迭代器Iterator,生成器Generator

什么是迭代器? 生成迭代器函数 什么是可迭代对象 原生可迭代对象 可迭代对象的应用 自定义类创建可迭代对象 在前面我们看到Array、Set、String、Map等类创建出来的对象都是可迭代对象 我们创建的类创建的对象是不可遍历的(迭代),要添加[Symbol.iterator]方法 迭代器的中断 在迭代器return方法中,返回done为true 什么是生成器? 普通函数执行过程 生成器函数的执行 当遇到yi...

yunbabac的博客 620

V8Js生成器双向传递完全指南:PHP与JavaScript之间的无缝协作

V8Js作为PHP的扩展模块,嵌入了强大的Google V8 JavaScript引擎,实现了PHP与JavaScript的高效互通。本文将深入探讨V8Js中生成器(Generator)的双向传递机制,帮助开发者掌握PHP与JavaScript之间数据流的无缝协作技巧。 ## 🚀 生成器双向传递基础:从概念到实践 生成器是ES6引入的重要特性,通过`function*`语法创建,能够暂停和恢

gitblog_00690的博客 965

JavaScript中的迭代器(iterator)和生成器(generator)详解

迭代器是一种思想,一种设计模式从一个数据集合中按照一定顺序,不断地取数据的过程迭代可以不确定取出的值有多少,也可以不取完所有数据,强调的是过程。遍历必须确定数据的长度,循环不断的全部取出,针对于数据量过大的情况下使用遍历,需要时间过长,强调的是结果。数组的迭代。...

weixin_57006241的博客 930

js 迭代器iterator 和 生成器Generator 10 (待补充)

✌。

m0_47186697的博客 209

JavaScript里的迭代器Iterator和生成器Generator(前端) async和await

JavaScript里的迭代器Iterator和生成器Generator(前端)

weixin_58555796的博客 400

JavaScript高级(十六)---Iterator迭代器/Generator生成器

迭代器是一种特殊的对象,这个对象需要符合迭代协议(iterator protocol),这个对象具有以下特点。该对象有一个特定的next方法next() {next() {例如:创建一个迭代器对象来访问数组next方法形参是一个无参数或者有一个参数的函数,返回一个应当拥有以下两个属性的对象如果迭代器可以产生序列中的下一个值,则为 false。如果迭代器已将序列迭代完毕,则为 true。这种情况下,value 是可选的,如果它依然存在,即为迭代结束之后的默认返回值。

Coder-coco的博客 820

新手小白入门必看教程,js中的迭代器 iterator 和生成器 generator 到底是什么

新手小白入门必看教程,js中的迭代器和生成器到底是什么

有一棵树的博客 387
上一篇: hot load那点事
下一篇: JavaScript 教程「7」:函数
梅花十三儿
博客等级 码龄5年 1038粉丝 444原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值