JavascriptのArray.prototype.map()を詳しく解説_基礎知識

WBOY
リリース: 2016-05-16 16:33:08
オリジナル
1195 人が閲覧しました

私たちの日常の開発では、配列の操作と変換は非常に一般的な操作です。例を見てみましょう。

コードをコピーします コードは次のとおりです:

var desColors = [],
srcColors = [
{r: 255, g: 255, b: 255}, // 白
{r: 128, g: 128, b: 128}, // グレー
{r: 0, g: 0, b: 0} // 黒
];

for (var i = 0, ilen = srcColors.length; i var color = srcColors[i],
形式 = 関数(色) {
return Math.round(color / 2);
};

desColors.push( {
r: フォーマット(color.r)、
g: format(color.g),
b: format(color.b)
});
}

// 出力:
// [
// {r: 128, g: 128, b: 128},
// {r: 64, g: 64, b: 64 },
// {r: 0, g: 0, b: 0 }
// ];
console.log(desColors);


上記の例からわかるように、すべての操作の繰り返し率は比較的高くなります。これを最適化するにはどうすればよいでしょうか? 幸いなことに、Ecmascript 5 には、上記の例を最適化するために使用できるマップ メソッドが用意されています。 >

コードをコピーします コードは次のとおりです:
var srcColors = [
{r: 255, g: 255, b: 255}, // 白
{r: 128, g: 128, b: 128}, // グレー
{r: 0, g: 0, b: 0} // 黒
]、
DesColors = srcColors.map(function(val) {
var format = function(color) {
return Math.round(color/2);
};
return {
r: format(val.r),
g: format(val.g),
b: format(val.b)
}
});
// 出力:
// [
// {r: 128, g: 128, b: 128},
// {r: 64, g: 64, b: 64 },
// {r: 0, g: 0, b: 0 }
// ];
console.log(desColors);

上記の例からわかるように、for ループ部分をマップを使用して置き換えているため、各要素自体の実装ロジックのみを気にする必要があります。地図作成方法の詳細はこちらをご覧ください。

1.マップの基本定義:
array.map(callback[, thisArg]);

map メソッドは、元の配列の各要素に対して 1 回ずつコールバック関数を順番に呼び出します。各コールバック実行後の戻り値が結合されて、新しい配列が形成されます。コールバック関数は、値を持つインデックスに対してのみ呼び出されます。値が割り当てられていないインデックスや、delete を使用して削除されたインデックスは呼び出されません。

コールバック関数は、配列要素、要素インデックス、元の配列自体の 3 つのパラメーターで自動的に渡されます。

thisArg パラメータに値がある場合、コールバック関数が呼び出されるたびに、thisArg パラメータのオブジェクトを指します。 thisArg パラメータが省略されている場合、または null または未定義に割り当てられている場合、これはグローバル オブジェクトを指します。

map は元の配列自体を変更しません (もちろん、コールバックの実行時に元の配列を変更することはできます)。

配列に対してマップ メソッドを実行すると、最初のコールバック メソッドが呼び出される前に配列の長さが決定されます。マップ メソッドの実行プロセス全体中、コールバック関数の操作によって元の配列に要素が追加されるか削除されるかは関係ありません。配列要素が増加すると、map メソッドは、新しく追加された要素がマップによって走査されなくなることを認識しません。配列要素が減少すると、map メソッドは元の配列の長さが変更されていないとみなします。その結果、次のような結果が得られます。範囲外の配列アクセス。配列内の要素が変更または削除された場合、コールバックに渡されるそれらの値は、map メソッドがそれらの要素を横断するときのその時点の値です。

2.マップインスタンス:

コードをコピーします コードは次のとおりです:

//例 1: 文字列に対してマップ メソッドを呼び出す
var result = Array.prototype.map.call("Hello world", function(x, Index, arr) {
//文字列 {0: "H"、1: "e"、2: "l"、3: "l"、4: "o"、5: " "、6: "w"、7: "o" 、8: "r"、9: "l"、10: "d"、長さ: 11}
console.log(arr);
x.charCodeAt(0);
を返す });
//出力: [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
console.log(結果);

上記の例は、文字列に対して map メソッドを使用して、文字列内の各文字に対応する ASCII コードで構成される配列を取得する方法を示しています。 console.log(arr) によって出力される結果に注目してください。

コードをコピーします コードは次のとおりです:

//例 2: 次の操作の結果はどうなりますか?
var result = ["1", "2", "3"].map(parseInt);
//出力: [1, NaN, NaN]
console.log(結果);

ご質問があるかもしれませんが、[1、2、3] はどうでしょうか? parseInt メソッドは 2 つのパラメータを受け取ることができることがわかっています。最初のパラメータは変換する必要がある値であり、2 番目のパラメータは基数です。理解できない場合は、ここをクリックしてください。 map メソッドを使用すると、コールバック関数は 3 つのパラメーターを受け取りますが、parseInt は最大 2 つのパラメーターしか受け取れないため、同時に、parseInt は渡されたインデックス値を基数として扱います。したがって、NaN が返されます。以下の出力を見てください:

コードをコピーします コードは次のとおりです:

//出力: 1
console.log(parseInt("1", 0));
//出力: 1
console.log(parseInt("1", 未定義));
//出力: NaN
console.log(parseInt("2", 1));
//出力: NaN
console.log(parseInt("3", 2));

最後の 2 つは理解するのが簡単ですが、最初の 2 つはなぜ 1 を返すのでしょうか?この問題を説明するために、公式の説明を見てみましょう:
基数が未定義または 0 (または存在しない) の場合、JavaScript は次のように想定します:
a) 入力文字列が「0x」または「0X」で始まる場合、基数は 16 (16 進数) で、文字列の残りの部分が解析されます。
b) 入力文字列が「0」で始まる場合、基数は 8 (8 進数) または 10 (10 進数) になります。正確にどの基数が選択されるかは、ECMAScript 5 では 10 (10 進数) が使用されると指定されています。すべてのブラウザがまだこれをサポートしているわけではありません。このため、parseInt.
を使用するときは常に基数を指定してください。 c) 入力文字列が他の値で始まる場合、基数は 10 (10 進数) です。
3 番目のポイントでは、string が別の値の場合、基数はデフォルトの 10 になります。

では、上記の例を正常に出力するにはどう変更すればよいでしょうか?次の例を見てください:

コードをコピー コードは次のとおりです:

var result = ["1", "2", "3"].map(function(val) {
parseInt(val, 10);
を返す });
//出力: [1, 2, 3]
console.log(結果);

3.マップメソッドの互換性:
マップ メソッドは、IE8 以前のブラウザではサポートされていません。古いバージョンのブラウザと互換性を持たせるには、次のことができます。

a) <font face="NSimsun">map</font> を使用しないでください。b) es5-shim などを使用して、古い IE をサポートします。<font face="NSimsun">map</font>。c) 同等のユーティリティ関数については、Underscore または Lodash の <font face="NSimsun">_.map</font> メソッドを使用します。

上記はマップ方法についての私の理解です。記事内の間違いがあれば修正していただければ幸いです。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート