Rumah >hujung hadapan web >tutorial js >Adakah anda tahu objek boleh lelar dan iterator dalam JavaScript?

Adakah anda tahu objek boleh lelar dan iterator dalam JavaScript?

醉折花枝作酒筹
醉折花枝作酒筹ke hadapan
2021-08-09 17:53:542709semak imbas

Lelaran ialah kaedah untuk mengakses elemen koleksi yang boleh diulang dipanggil objek boleh diulang; telah diakses, iterator hanya boleh bergerak ke hadapan dan bukan ke belakang.

Penilaian malas

Penilaian malas sering diterjemahkan sebagai "pengiraan tertunda" atau "pengiraan malas", yang merujuk kepada pengiraan nilai ungkapan hanya apabila ia benar-benar diperlukan untuk dilaksanakan.

Kebalikan daripada penilaian malas ialah penilaian awal, juga dikenali sebagai penilaian tamak atau penilaian ketat, ialah strategi penilaian kebanyakan bahasa pengaturcaraan tradisional.

Faedah memanfaatkan sepenuhnya ciri penilaian malas terutamanya ditunjukkan dalam dua aspek berikut:

  • Elakkan pengiraan yang tidak perlu dan tingkatkan prestasi.

  • Menjimatkan ruang menjadikan struktur data gelung tak terhingga mungkin.

Iterators

Iterators dalam ES6 memungkinkan untuk malas menilai dan mencipta jujukan data yang ditentukan pengguna. Lelaran ialah mekanisme untuk melintasi data. Iterator ialah penunjuk yang digunakan untuk melintasi unsur-unsur struktur data (dipanggil Iterable), penunjuk yang digunakan untuk menghasilkan urutan nilai.

Lelaran ialah objek yang boleh diulang. Ia mengabstrakkan bekas data supaya ia berkelakuan seperti objek boleh lelaran.

Iterators tidak mengira nilai setiap item apabila digunakan dan hanya menjana nilai seterusnya apabila diminta. Ini sangat berguna, terutamanya untuk set data besar atau jujukan elemen tak terhingga.

Objek Boleh Lelar

Objek boleh lelar ialah struktur data yang mahu elemennya boleh diakses secara umum. Banyak objek dalam JS boleh diulangi mungkin tidak mudah dikesan, tetapi jika anda meneliti dengan teliti, anda akan menemui ciri-ciri lelaran:

  • Peta baharu([iterable])

  • WeakMap baharu([iterable])

  • Set baharu([iterable])

  • WeakSet baharu ([iterable])

  • Promise.all([iterable])

  • Promise.race([iterable])

  • Array.from([iterable])

juga memerlukan objek iterable, jika tidak, ia akan membuang ralat jenis, contohnya:

  • untuk ... daripada

  • ... (operator kembangkan)
    const [a, b, ..] = boleh lelar (memusnahkan tugasan)

  • hasil* (penjana)

Terdapat banyak item lelaran terbina dalam dalam JavaScript:

String,Array,TypedArray , Peta, Set.

Protokol lelaran

Iterator dan objek boleh lelaran mengikut protokol lelaran.

Protokol ialah satu set antara muka dan menentukan cara menggunakannya.

Iterators mengikut protokol iterator, dan iterable mengikut protokol iterable.

Protokol boleh lelar

Untuk menjadikan objek boleh lelar, ia mesti melaksanakan kaedah lelaran melalui Symbol.iterator, iaitu kilang untuk lelaran .

Menggunakan TypeScript, protokol lelaran kelihatan seperti ini:

interface Iterable {
  [Symbol.iterator]() : Iterator;
}

Symbol.iterator]() ialah fungsi tanpa parameter. Memanggilnya pada objek boleh lelar bermakna kita boleh mengakses objek boleh lelar melalui ini, yang boleh menjadi fungsi biasa atau fungsi penjana.

Protokol Iterator

Protokol iterator mentakrifkan cara standard untuk menghasilkan jujukan nilai.

Untuk membolehkan objek menjadi lelaran, ia mesti melaksanakan kaedah seterusnya(). Iterator boleh melaksanakan kaedah return(), yang akan kita bincangkan kemudian dalam artikel ini.

Menggunakan TypeScript, protokol iterator kelihatan seperti ini:

interface Iterator {
    next() : IteratorResult;
    return?(value?: any): IteratorResult;
}

IteratorResult ditakrifkan seperti berikut:

interface IteratorResult {
    value?: any;
    done: boolean;
}
  • selesai memberitahu pengguna untuk lelaran Sama ada iterator telah digunakan, false bermakna masih ada nilai yang perlu dijana, benar bermakna iterator telah tamat.

  • nilai boleh menjadi sebarang nilai JS, ia adalah nilai yang dipaparkan kepada pengguna.

Apabila dilakukan adalah benar, nilai boleh ditinggalkan.

Komposisi

Iterator dan objek boleh lelar boleh diwakili oleh gambar berikut:

Adakah anda tahu objek boleh lelar dan iterator dalam JavaScript?

Contoh

Pengetahuan asas mempunyai telah diperkenalkan. Seterusnya, mari kita gunakan beberapa contoh untuk memperdalam imej kita.

Peulang julat

Kami bermula dengan lelaran yang sangat asas, lelaran createRangeIterator.

Kami memanggilnya secara manual.next() untuk mendapatkan IteratorResult seterusnya. Panggilan terakhir mengembalikan {done: true}, yang bermaksud iterator kini digunakan dan tidak lagi menghasilkan sebarang nilai.

function createRangeIterator(from, to) {
  let i = from;

  return {
    next() {
      if (i <= to) {
        return { value: i++, done: false };
      } else {
        return { done: true };
      }
    }
  }
}

const it = createRangeIterator(1, 3);

console.log(it.next());
console.log(it.next());
console.log(it.next());
console.log(it.next());

Adakah anda tahu objek boleh lelar dan iterator dalam JavaScript?

Peulang julat boleh lelar

Terdahulu dalam artikel ini, saya telah menyebut penyataan tertentu dalam JS Memerlukan objek boleh lelaran. Oleh itu, contoh terdahulu kami tidak akan berfungsi apabila digunakan dengan gelung for...of.

Tetapi sangat mudah untuk mencipta objek yang mematuhi protokol iterator dan boleh lelar.

Adakah anda tahu objek boleh lelar dan iterator dalam JavaScript?

function createRangeIterator (from, to) {
  let i = from

  return {
    [Symbol.iterator] () {
      return this
    },
    next() {
      if (i <= to) {
        return { value: i++, done: false }
      } else {
        return { done: true }
      }
    }
  }
}

const it = createRangeIterator(1, 3)

for (const i of it) {
  console.log(i)
}

无限序列迭代器

迭代器可以表示无限制大小的序列,因为它们仅在需要时才计算值。

注意不要在无限迭代器上使用扩展运算符(...),JS 将尝试消费迭代器,由于迭代器是无限的,因此它将永远不会结束。 所以你的应用程序将崩溃,因为内存已被耗尽 

同样,for ... of 循环也是一样的情况,所以要确保能退出循环:

function createEvenNumbersIterator () {
  let value = 0

  return {
    [Symbol.iterator] () {
      return this
    },
    next () {
      value += 2
      return { value, done: false}
    }
  }
}

const it = createEvenNumbersIterator()

const [a, b, c] = it
console.log({a, b, c})

const [x, y, z] = it
console.log({ x, y, z })

for (const even of it) {
  console.log(even)
  if (even > 20) {
    break
  }
}

Adakah anda tahu objek boleh lelar dan iterator dalam JavaScript?

关闭迭代器

前面我们提到过,迭代器可以有选择地使用return()方法。 当迭代器直到最后都没有迭代时使用此方法,并让迭代器进行清理。

for ... of循环可以通过以下方式更早地终止迭代:

  • break

  • continue

  • throw

  • return

function createCloseableIterator () {
  let idx = 0
  const data = [&#39;a&#39;, &#39;b&#39;, &#39;c&#39;, &#39;d&#39;, &#39;e&#39;]

  function cleanup() {
    console.log(&#39;Performing cleanup&#39;)
  }
  return {
    [Symbol.iterator]() { return this },
    next () {
      if (idx <= data.length - 1) {
        return { value: data[idx++], done: false }
      } else {
        cleanup()
        return { done: true }
      }
    },
    return () {
      cleanup()
      return { done: true }
    }
  }
}

const it = createCloseableIterator()

for (const value of it) {
  console.log(value)
  if (value === &#39;c&#39;) {
    break
  }
}

console.log(&#39;\n----------\n&#39;)

const _it = createCloseableIterator();
for (const value of _it) {
  console.log(value);
}

Adakah anda tahu objek boleh lelar dan iterator dalam JavaScript?

  • 如果知道迭代器已经结束,则手动调用cleanup()函数。

  • 如果突然完成,则return()起作用并为我们进行清理。

【推荐学习:javascript高级教程

Atas ialah kandungan terperinci Adakah anda tahu objek boleh lelar dan iterator dalam JavaScript?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:segmentfault.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam