私がmapとforeachで見る唯一の違いは、map
が配列を返し、forEach
が返さないことです。ただし、forEach
メソッドの最後の行 "func.call(scope, this[i], i, this);
"も理解していません。たとえば、「this
」と「scope
」は同じオブジェクトを参照せず、this[i]
とi
は現在の値を参照しませんループ?
別の投稿で、誰かが「リストの各要素に基づいて何かをしたいときにforEach
を使用してください。たとえば、ページに何かを追加しているかもしれません。本質的に、 「副作用」が必要です副作用の意味がわかりません.
Array.prototype.map = function(fnc) {
var a = new Array(this.length);
for (var i = 0; i < this.length; i++) {
a[i] = fnc(this[i]);
}
return a;
}
Array.prototype.forEach = function(func, scope) {
scope = scope || this;
for (var i = 0, l = this.length; i < l; i++) {
func.call(scope, this[i], i, this);
}
}
最後に、javascriptでこれらのメソッドを実際に使用する方法はありますか(データベースを更新していないため)。
alert([1,2,3,4].map(function(x){ return x + 1})); //this is the only example I ever see of map in javascript.
返信いただきありがとうございます。
あなたの例のmap
とforEach
の本質的な違いは、forEach
は元の配列要素に対して動作するのに対し、map
は結果として新しい配列を明示的に返すことです。 。
forEach
を使用すると、元の配列の各要素を使用して(およびオプションで変更を使用して)アクションを実行します。 forEach
メソッドは、各要素に指定した関数を実行しますが、何も返しません(undefined
)。一方、map
は配列を調べ、各要素に関数を適用し、結果を新しい配列として出力します。
forEach
の「副作用」は、元の配列が変更されることです。 map
による「副作用なし」は、慣用的な使用法では、元の配列要素がnot変更されたことを意味します。新しい配列は、元の配列の各要素の1対1マッピングです。マッピング変換は、提供された関数です。
データベースが含まれていないという事実は、データ構造を操作する必要がないという意味ではありません。これは、結局のところ、どの言語でもプログラミングの本質の1つです。最後の質問に関しては、配列には数字だけでなく、オブジェクト、文字列、関数などを含めることができます。
2つの方法の主な違いは概念とスタイルです:何かをしたいときにforEach
を使用しますtoまたはwith配列の各要素( "with"を行うことは、引用した投稿が "副作用"を意味するものだと思います)、コピーしたい場合はmap
を使用しますそして、(元を変更せずに)配列の各要素を変換します。
map
とforEach
の両方が配列内の各項目で関数を呼び出し、その関数はユーザー定義であるため、一方ではできても他方ではできないことはほとんどありません。いですが、map
を使用して、配列をインプレースで変更したり、配列要素で何かをしたりできます。
var a = [{ val: 1 }, { val: 2 }, { val: 3 }];
a.map(function(el) {
el.val++; // modify element in-place
alert(el.val); // do something with each element
});
// a now contains [{ val: 2 }, { val: 3 }, { val: 4 }]
forEach
を使用する意図については、より明確で明確です。
var a = [{ val: 1 }, { val: 2 }, { val: 3 }];
a.forEach(function(el) {
el.val++;
alert(el.val);
});
特に、現実の世界では通常そうであるように、el
は人間が読むことができる便利な変数です。
cats.forEach(function(cat) {
cat.meow(); // nicer than cats[x].meow()
});
同様に、forEach
を使用して新しい配列を簡単に作成できます。
var a = [1,2,3],
b = [];
a.forEach(function(el) {
b.Push(el+1);
});
// b is now [2,3,4], a is unchanged
ただし、map
を使用するとよりクリーンになります。
var a = [1,2,3],
b = a.map(function(el) {
return el+1;
});
また、map
は新しい配列を作成するため、特に大規模な配列の場合に反復が必要な場合、少なくともパフォーマンス/メモリヒットが発生する可能性が高いことに注意してください- http://jsperf.comを参照/ map-foreach
これらの関数を使用する理由については、JavaScriptで配列操作を行う必要があるときはいつでも役立ちます(ブラウザ環境でJavaScriptについて話しているだけでも)、ほとんどの場合コードに手で書き留めていない配列にアクセスしています。ページ上のDOM要素の配列、またはAJAXリクエストからプルされたデータ、またはユーザーがフォームに入力したデータを処理している可能性があります。外部APIから、map
を使用してデータを目的の形式に変換し、forEach
を使用して新しい配列を反復処理してユーザーに表示します。
投票された回答(Ken Redlerから)は誤解を招きます。
コンピューターサイエンスの副作用は、関数/メソッドのプロパティがグローバル状態を変更することを意味します [wiki] 。狭い意味では、これには引数からではなく、グローバル状態からの読み取りも含まれます。命令型またはOOプログラミングでは、ほとんどの場合、副作用が発生します。おそらく、気付かないうちにそれを使用している可能性があります。
forEach
とmap
の重要な違いは、map
がメモリを割り当てて戻り値を格納するのに対し、forEach
はそれを破棄することです。詳細については、 emca spec を参照してください。
副作用が必要なときにforEach
が使用されると言う理由は、forEach
の戻り値が常にundefined
であるためです。副作用がない(グローバルステートを変更しない)場合、関数はCPU時間を無駄にしています。最適化コンパイラは、このコードブロックを削除し、最終値(undefined
)に置き換えます。
ところで、JavaScriptには副作用に対する制限がないことに注意してください。 map
内の元の配列を引き続き変更できます。
var a = [1,2,3]; //original
var b = a.map( function(x,i){a[i] = 2*x; return x+1} );
console.log("modified=%j\nnew array=%j",a,b);
// output:
// modified=[2,4,6]
// new array=[2,3,4]
以下は Array.prototype.map()
の公式の説明 に基づいています。
nothingがあり、forEach()
はできますが、map()
はできません。つまり、map()
は、forEach()
のstrict super-setです。
map()
は通常、新しい配列を作成するために使用されますが、現在の配列を変更するためにalsoも使用できます。以下に例を示します。
_var a = [0, 1, 2, 3, 4], mapped = null;
mapped = a.map(function (x) { a[x] = x*x*x; return x*x; });
console.log(mapped); // logs [0, 1, 4, 9, 16] As expected, these are squares.
console.log(a); // logs [0, 1, 8, 27, 64] These are cubes of the original array!!
_
上記の例では、a
は、_a[i] === i
_が_i < a.length
_になるように便利に設定されていました。それでも、それはmap()
の力、特に呼び出される配列を変更する能力を示しています。
注1:
公式の説明は、map()
が呼び出される配列の長さlengthを変更する可能性があることを暗示しています!ただし、これを行う(正当な)理由がわかりません。
注2:
_map()
マップはforEach()
のスーパーセットですが、特定の配列を変更したい場合はforEach()
を使用する必要があります。これにより、意図が明確になります。
これが役に立てば幸いです。
map
であるかのようにforEach
を使用できます。
ただし、必要以上のことを行います。
scope
は任意のオブジェクトにすることができます。必ずしもthis
ではありません。
map
およびforEach
の実際の使用があるかどうか、およびfor
またはwhile
ループの実際の使用があるかどうかを尋ねます。
上記の質問はすべて正しいですが、私は間違いなく別の区別をします。 map
とforEach
の使用は意図を暗示することができます。
何らかの方法で既存のデータを単純に変換するときに(ただし、元のデータが変更されていないことを確認したい場合)、map
を使用するのが好きです。
コレクションを適切に変更するときは、forEach
を使用するのが好きです。
例えば、
var b = [{ val: 1 }, { val: 2 }, { val: 3 }];
var c = b.map(function(el) {
return { val: el.val + 1 }; // modify element in-place
});
console.log(b);
// [{ val: 1 }, { val: 2 }, { val: 3 }]
console.log(c);
// [{ val: 3 }, { val: 4 }, { val: 5 }]
私の経験則では、map
を実行するときは、単にソースリストの各要素に対して返される新しいオブジェクト/値を作成し、returningで単に操作を実行するのではなく、各要素。
既存のリストを実際に変更する必要がない限り、その場でリストを変更することは実際には意味がなく、機能的/不変のプログラミングスタイルにより適しています。
再び、私はネクロマンサーが5年前に尋ねられた質問に回答を追加しているように感じます(幸いなことに、最近の活動があるので、死者を邪魔するのは私だけではありません)。
他の人は、機能の違いに関する主な質問についてすでに投稿しています。しかし...
javascriptでこれらのメソッドを実際に使用する方法はありますか(データベースを更新していないため)。
...おかしいです。ちょうど今日、変換のためにmapを使用して、正規表現の値を複数の変数に割り当てるコードを作成しました。非常に複雑なテキストベースの構造を視覚化可能なデータに変換するために使用されました...しかし、簡単にするために、日付文字列を使用した例を提供します。 、mapの代わりにDate-objectを使用します。Date-objectは、それ自体で見事にジョブを実行します)。
const DATE_REGEXP = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2})\.(\d{3})Z$/;
const TEST_STRING = '2016-01-04T03:20:00.000Z';
var [
iYear,
iMonth,
iDay,
iHour,
iMinute,
iSecond,
iMillisecond
] = DATE_REGEXP
// We take our regular expression and...
.exec(TEST_STRING)
// ...execute it against our string (resulting in an array of matches)...
.slice(1)
// ...drop the 0th element from those (which is the "full string match")...
.map(value => parseInt(value, 10));
// ...and map the rest of the values to integers...
// ...which we now have as individual variables at our perusal
console.debug('RESULT =>', iYear, iMonth, iDay, iHour, iMinute, iSecond, iMillisecond);
したがって...これは単なる例であり、データの非常に基本的な変換のみを行いました(例のためだけ)...マップなしでこれを行うと、はるかに退屈な作業になります。
確かに、JavaScriptのバージョンで書かれているので、あまり多くのブラウザーがサポートしているとは思わないまだ(少なくとも完全に)だが、私たちはそこに着いている。ブラウザで実行する必要がある場合、うまく変換できると思います。
TL; DR回答-
mapは常に別の配列を返します。
forEachはしません。何をするかはあなた次第です。必要な場合は配列を返し、不要な場合は他の操作を行います。
特定の状況では柔軟性が望ましい。あなたが扱っているもののためではない場合は、マップを使用してください。