ホームページ  >  記事  >  ウェブフロントエンド  >  ES6のforとforeachの違いは何ですか

ES6のforとforeachの違いは何ですか

青灯夜游
青灯夜游オリジナル
2022-10-21 17:32:541526ブラウズ

違い: 1. forEach は反復可能オブジェクト (配列セット マップ) の走査を担当する反復子ですが、for は配列のみを走査できるループ メカニズムです。 2. 一部の割り込み動作は for ループで使用されており、配列の走査と検索の最適化に適していますが、forEach は反復子であり、順番にのみ走査できるため、割り込み動作はサポートされていません。 3. forEach ループの開始点は 0 のみであり、人間の介入は不可能です。for ループとは異なり、ループの開始点は手動で制御できます。

ES6のforとforeachの違いは何ですか

このチュートリアルの動作環境: Windows 7 システム、ECMAScript バージョン 6、Dell G3 コンピューター。

for ループと forEach の本質的な違い

forLoop は、js で導入されたループ メソッドです。

forEach は ES5 によって提案されたメソッドであり、Array Set Map# などの反復可能なオブジェクトのプロトタイプにマウントされています。 ##。

forEach は反復子であり、反復可能なオブジェクトの走査を担当します。

それでは、

traversaliterationiterable object とはそれぞれ何ですか。

  • トラバーサル: データ構造の各メンバーへの定期的および 1 回限りのアクセス動作を指します。

  • 反復: 反復は特別な形式の再帰であり、反復子によって提供されるメソッドです。デフォルトでは、特定の順序です1 つずつデータ構造メンバーにアクセスします。反復も走査動作です。

  • Iterable object: iterable 型は ES6 で導入されました、Array Set Map String arguments NodeList はすべて iterable に属しており、その特徴はすべて [Symbol を持っていることです。 .iterator] メソッドを含むオブジェクトは、反復可能な iterable とみなされます。

forEach は実際には反復子です。これと for ループの本質的な違いは、forEach が役割を担うことです。 for traversing (Array Set Map) Iterable オブジェクト、および for ループはループ機構であり、 array のみを走査できます。

iteratorとは? 呼び出すとイテレータオブジェクト(Iterator Object)が生成され、.next()メソッドを持っています。呼び出しはオブジェクト {value:value,done:Boolean} を返します。value は、yield の後で、yieldEnd のときに戻り値を返します。 donetrue になり、内部値は継続的な呼び出しと連続した反復を通じてアクセスされます。

Iterator は特別なオブジェクトです。 ES6 仕様におけるそのシンボルは、返されるオブジェクトの next() メソッドであり、反復動作は done で判断されます。イテレータは、内部表現を公開せずにトラバーサルを実装します。コード

let arr = [1, 2, 3, 4]  // 可迭代对象
let iterator = arr[Symbol.iterator]()  // 调用 Symbol.iterator 后生成了迭代器对象
console.log(iterator.next()); // {value: 1, done: false}  访问迭代器对象的next方法
console.log(iterator.next()); // {value: 2, done: false}
console.log(iterator.next()); // {value: 3, done: false}
console.log(iterator.next()); // {value: 4, done: false}
console.log(iterator.next()); // {value: undefined, done: true}
を見ると、次のことが分かります。反復可能なオブジェクトである限り、内部

Symbol.iterator を呼び出すと反復子が提供され、反復子によって返される next メソッド (これも # ) に基づいて内部にアクセスします。 ##for..of の実装原理。 <pre class="brush:php;toolbar:false">let arr = [1, 2, 3, 4] for (const item of arr) {     console.log(item); // 1 2 3 4  }</pre>

next

メソッドを呼び出してオブジェクトの value 値を返し、それを value まで item に保存します。 is unknown ループから抜け出すと、すべての反復可能なオブジェクトが for...of で使用できるようになります。他の反復​​可能オブジェクトを見てみましょう: <pre class="brush:php;toolbar:false">function num(params) {     console.log(arguments); // Arguments(6) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ]     let iterator = arguments[Symbol.iterator]()     console.log(iterator.next()); // {value: 1, done: false}     console.log(iterator.next()); // {value: 2, done: false}     console.log(iterator.next()); // {value: 3, done: false}     console.log(iterator.next()); // {value: 4, done: false}     console.log(iterator.next()); // {value: undefined, done: true} } num(1, 2, 3, 4) let set = new Set('1234') set.forEach(item =&gt; {     console.log(item); // 1 2 3 4 }) let iterator = set[Symbol.iterator]() console.log(iterator.next()); // {value: 1, done: false} console.log(iterator.next()); // {value: 2, done: false} console.log(iterator.next()); // {value: 3, done: false} console.log(iterator.next()); // {value: 4, done: false} console.log(iterator.next()); // {value: undefined, done: true}</pre>したがって、反復可能オブジェクトの

Symbol.iterator

プロパティは、呼び出されたときに反復子を生成でき、forEach も生成されます。内部コールバック関数

for<span style="font-size: 20px;"></span>loopおよび ##の各要素の値を渡すイテレータ#forEach<span style="font-size: 20px;"></span><span style="font-size: 20px;"></span>

#各のパラメータ。

割り込み。

  • forEach 独自の要素を削除すると、インデックスをリセットできなくなります。

  • #for ループはループの開始点を制御できます。

  • forEach

  • のパラメータ forEach のパラメータの完全な内容を本当に理解していますか?おそらく次のようになります:

    arr.forEach((self,index,arr) =>{},this)

self: 現在配列によって走査されている要素。デフォルトでは、配列要素は左から右に取得されます。

############index: ### 配列の現在の要素のインデックス。最初の要素のインデックスは 0 などです。 ################arr: ### 現在走査されている配列。 ###############this: ### これはコールバック関数を指します。 #########
let arr = [1, 2, 3, 4];
arr.forEach(function (self, index, arr) {
    console.log(`当前元素为${self}索引为${index},属于数组${arr}`);
}, person)
######arr### を使用して配列の重複排除を実現できます: ###
let arr1 = [1, 2, 1, 3, 1];
let arr2 = [];
arr1.forEach(function (self, index, arr) {
    arr.indexOf(self) === index ? arr2.push(self) : null;
});
console.log(arr2);   // [1,2,3]

forEach 的中断

在js中有break return continue 对函数进行中断或跳出循环的操作,我们在 for循环中会用到一些中断行为,对于优化数组遍历查找是很好的,但由于forEach属于迭代器,只能按序依次遍历完成,所以不支持上述的中断行为。

let arr = [1, 2, 3, 4],
    i = 0,
    length = arr.length;
for (; i < length; i++) {
    console.log(arr[i]); //1,2
    if (arr[i] === 2) {
        break;
    };
};

arr.forEach((self,index) => {
    console.log(self);
    if (self === 2) {
        break; //报错
    };
});

arr.forEach((self,index) => {
    console.log(self);
    if (self === 2) {
        continue; //报错
    };
});

如果我一定要在 forEach 中跳出循环呢?其实是有办法的,借助try/catch

try {
    var arr = [1, 2, 3, 4];
    arr.forEach(function (item, index) {
        //跳出条件
        if (item === 3) {
            throw new Error("LoopTerminates");
        }
        //do something
        console.log(item);
    });
} catch (e) {
    if (e.message !== "LoopTerminates") throw e;
};

若遇到 return 并不会报错,但是不会生效

let arr = [1, 2, 3, 4];

function find(array, num) {
    array.forEach((self, index) => {
        if (self === num) {
            return index;
        };
    });
};
let index = find(arr, 2);// undefined

forEach 删除自身元素,index不可被重置

forEach 中我们无法控制 index 的值,它只会无脑的自增直至大于数组的 length 跳出循环。所以也无法删除自身进行index重置,先看一个简单例子:

let arr = [1,2,3,4]
arr.forEach((item, index) => {
    console.log(item); // 1 2 3 4
    index++;
});

index不会随着函数体内部对它的增减而发生变化。在实际开发中,遍历数组同时删除某项的操作十分常见,在使用forEach删除时要注意。

for 循环可以控制循环起点

如上文提到的 forEach 的循环起点只能为0不能进行人为干预,而for循环不同:

let arr = [1, 2, 3, 4],
    i = 1,
    length = arr.length;

for (; i < length; i++) {
    console.log(arr[i]) // 2 3 4
};

那之前的数组遍历并删除滋生的操作就可以写成

let arr = [1, 2, 1],
    i = 0,
    length = arr.length;

for (; i < length; i++) {
    // 删除数组中所有的1
    if (arr[i] === 1) {
        arr.splice(i, 1);
        //重置i,否则i会跳一位
        i--;
    };
};
console.log(arr); // [2]
//等价于
var arr1 = arr.filter(index => index !== 1);
console.log(arr1) // [2]

<span style="font-size: 18px;">for</span>循环和<span style="font-size: 18px;">forEach</span>的性能区别

在性能对比方面我们加入一个 map 迭代器,它与 filter 一样都是生成新数组。

对比 for forEach map 的性能在浏览器环境中都是什么样的:

性能比较:for > forEach > map 在chrome 62 和 Node.js v9.1.0环境下:for 循环比 forEach 快1倍,forEachmap 快20%左右。

原因分析for:for循环没有额外的函数调用栈和上下文,所以它的实现最为简单。

forEach:对于forEach来说,它的函数签名中包含了参数和上下文,所以性能会低于 for 循环。

mapmap 最慢的原因是因为 map 会返回一个新的数组,数组的创建和赋值会导致分配内存空间,因此会带来较大的性能开销。

如果将map嵌套在一个循环中,便会带来更多不必要的内存消耗。

当大家使用迭代器遍历一个数组时,如果不需要返回一个新数组却使用 map 是违背设计初衷的。

【相关推荐:javascript视频教程编程视频

以上がES6のforとforeachの違いは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。