本文介绍了map给我们的js编程带来的好处及便利:
1.Map能干什么
map可以实现for循环的功能:
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body> <script> var arr = ['val1', 'val2', 'val3']; for(var i = 0; i < arr.length; i++){ console.log(arr[i]); console.log(i); console.log(arr); } arr.map(function(val, index, array) { console.log(val); console.log(index); console.log(array); }); </script> </body> </html>
这里的好处是,我们可以随意在map里面写函数,这样的话代码可读性会大大提高,如下:
function output(val, index, array) { console.log(val); console.log(index); console.log(array); } arr.map(output);
2.Map的兼容性
ECMAScript 5 标准定义了原生的 map() 方法,所以浏览器兼容性较好。如果你想在 IE 9 之前的版本中使用,就需要引入一个 polyfill 或使用 Underscore、Lodash 之类的库了。
3.map和for哪个快
当然,使用for会比map快点,但是差别不是很大,如果对性能要求没有到极致的地步,这点性能差别可以忽略。
如今,在程序员学习过程中基本都会发现一个叫 map 的函数。在发现 map 函数之前,你可能都会使用 for 循环来处理需要多次执行某一行为的场景。一般情况下,在这个循环过程中都会伴随一些数据变换。
命令式
例如,你团队的销售人员交给你一个很长的电邮地址列表。这些邮箱地址获取的时候并没有经过很好地校验,以至于有些是大写的,有些是小写的,还有一些是大小写混合的。使用 for 循环进行数据处理的代码如下:
var mixedEmails = ['JOHN@ACME.COM', 'Mary@FooBar.com', 'monty@spam.eggs']; function getEmailsInLowercase(emails) { var lowercaseEmails = []; for (var i = 0; i < emails.length; i++) { lowercaseEmails.push(emails[i].toLowerCase()); } return lowercaseEmails; } var validData = getEmailsInLowercase(mixedEmails);
这样的做法是有效的,但却把一个实际上简单常见的操作变得复杂。使用 for 循环的函数牵扯了很多不必要的细节。一些痛点如下:
这是命令式的编程方法。我们似乎在口述给电脑该怎么做这件事。
困惑
为了使之前的代码更加清晰整洁,我们改用 map 函数。在任何 map 函数的说明文档中,我们都会看到诸如 “array”、“each”、“index”之类的词。这表明,我们可以把 map 当做不那么“隆重”的 for 循环使用,事实上也是可行的。现在来修改一下之前的代码:
var mixedEmails = ['JOHN@ACME.COM', 'Mary@FooBar.com', 'monty@spam.eggs']; function getEmailsInLowercase(emails) { var lowercaseEmails = []; emails.map(function(email) { lowercaseEmails.push(email.toLowerCase()); }); return lowercaseEmails; } var validData = getEmailsInLowercase(mixedEmails);
这样写不仅能用,而且代码比使用 for 循环更加清楚。除了代码量更少,我们也不用再告诉程序去记录索引和遍历列表的方向了。
然而,这还不够好。这样写还是命令式的编程。我们还是指挥的太多。实际上我们牵涉了很多不必要的细节,似乎都在领着程序的手走每一步。
声明式
我们需要改变我们关于数据变换的思考方式。我们不需要想着:“电脑啊,我需要你取出列表中第一个元素,然后把它转换成小写,再存储到另一个列表中,最后返回这个列表”。相反,我们应该这样想:“电脑,我这有一个混合了大小写的邮件地址列表,而我需要一个全是小写的邮件地址列表,这是一个能够进行小写转换的函数”。
var mixedEmails = ['JOHN@ACME.COM', 'Mary@FooBar.com', 'monty@spam.eggs']; function downcase(str) { return str.toLowerCase(); } var validData = mixedEmails.map(downcase);
この書き方の方が理解しやすいのは間違いありません。これがプログラミングの本質です。自分のアイデアを他の人に伝えることです。この人は他のプログラマーかもしれないし、将来はあなたかもしれません。上記のコードは、「有効なデータは小文字変換関数を使用してマッピングされたメールボックス リストである」ことを示しています。
このような高度な方法を使用してアイデアを伝達することは、関数型プログラミングの中核原則であり、私たちはまさにそれを行っています。理解しやすい単一の機能と単純な部品を組み合わせて、複雑なプログラムを構築します。
この書き方にはさらにいくつかの利点があります。次の表は順不同です:
マップの最初のパラメータに匿名関数を渡すのが一般的ですが、関数を抽出して適切な名前を付けることをお勧めします。これは、この関数を作成した意図を記録するのに役立ち、他の開発者がコードを分析しなくても関数名を通じて関数を理解できるようになります。
ブラウザのサポート
ECMAScript 5 標準ではネイティブの map() メソッドが定義されているため、ブラウザの互換性が向上しています。 IE 9より前のバージョンで使用したい場合は、ポリフィルを導入するか、UnderscoreやLodashなどのライブラリを使用する必要があります。
パフォーマンス
ほとんどの場合、実際のコーディングではマップ関数と for ループの間に明らかなパフォーマンスのギャップはありません。 for ループはわずかに高速ですが、グラフィックス エンジンや物理エンジンを作成していない場合は、この違いを考慮する必要はありません。もちろん、それでも、これらのパフォーマンスの向上が役立つと確信している場合を除き、この違いを考慮するのは理にかなっています。このように最適化するのは大したことではありません。
概要
ロジックを単一関数のメソッドに分割し、それらをデータ構造に適用すると、コードがより正確で堅牢になり、理解しやすくなります。私たちの哲学は、コードを再利用しやすくするために、可能な限り一般的であることです。この考え方を学ぶことは、JavaScript スキルの向上に役立つだけでなく、Ruby や Haskell などの他のほとんどのプログラミング言語にも反映できます。
それで、次に for ループを使用するときは、もう一度考えてください。処理するデータは必ずしも通常の配列である必要はないことに注意してください。オブジェクトを処理し、その値を取り出し、関数を使用してマップし、最後に結果の配列を並べ替えることができます。
上記はループではなくマップについての簡単な紹介です。皆さんの学習に役立つことを願っています。