{"id":13604,"date":"2019-01-21T07:31:00","date_gmt":"2019-01-21T06:31:00","guid":{"rendered":"http:\/\/touk.pl\/blog\/?guid=4b9b4faba5aa105a019aa2d656aec111"},"modified":"2023-03-16T13:55:46","modified_gmt":"2023-03-16T12:55:46","slug":"not-so-easy-functional-programming-in-javascript","status":"publish","type":"post","link":"https:\/\/touk.pl\/blog\/2019\/01\/21\/not-so-easy-functional-programming-in-javascript\/","title":{"rendered":"Not so easy functional programming in JavaScript"},"content":{"rendered":"<h2 id=\"introduction\">Introduction<\/h2>\n<p>JavaScript allows for operating on arrays in a functional way, e.g. using <code>filter<\/code> or <code>map<\/code> functions. As an argument for these functions we can pass lambda expression or function reference. Is there a difference between them? The answer is yes.<\/p>\n<h2 id=\"whats-the-problem\">What&#8217;s the problem?<\/h2>\n<p>In our project we are building a mapping using <code>String.fromCharCode<\/code> function. To simplify the usage of this function looked similar to:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">[66, 67, 68].map(v =&gt; String.fromCharCode(v))<\/pre>\n<p>When we run this code with node we received <code>[ 'B', 'C', 'D' ]<\/code>, but when we decided to refactor it to use function reference the result was different:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&gt; [66, 67, 68].map(String.fromCharCode)\r\n[ 'B\\u0000\\u0000', 'C\\u0001\\u0000', 'D\\u0002\\u0000' ]<\/pre>\n<h2 id=\"what-happened\">What happened?<\/h2>\n<p>To find the reason for this behavior, let&#8217;s first play with function <code>String.fromCharCode<\/code> alone:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&gt; String.fromCharCode(66)\r\n'B'\r\n&gt; String.fromCharCode([66, 67, 68])\r\n'\\u0000'\r\n&gt; String.fromCharCode(66, 67, 68)\r\n'BCD'\r\n<\/pre>\n<p><code>String.fromCharCode<\/code> deals with various types and numbers of arguments.<\/p>\n<p>Now, let&#8217;s examine the function <code>map<\/code>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&gt; [66, 67, 68].map(v =&gt; v)\r\n[ 66, 67, 68 ]\r\n&gt; [66, 67, 68].map((v, u) =&gt; [v, u])\r\n[ [ 66, 0 ], [ 67, 1 ], [ 68, 2 ] ]\r\n&gt; [66, 67, 68].map((v, u, w) =&gt; [v, u, w])\r\n[ [ 66, 0, [ 66, 67, 68 ] ],\r\n  [ 67, 1, [ 66, 67, 68 ] ],\r\n  [ 68, 2, [ 66, 67, 68 ] ] ]<\/pre>\n<p><code>map<\/code>, like many other array functions, passes always <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Array\/map#Syntax\">three arguments to function<\/a>. First is the current value, the second is the index of the current value and third is the whole array.<\/p>\n<p>It means that passing <code>String.fromCharCode<\/code> to <code>map<\/code> function under the hood looks like this:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&gt; [66, 67, 68].map((v, u, w) =&gt; String.fromCharCode(v, u, w))\r\n[ 'B\\u0000\\u0000', 'C\\u0001\\u0000', 'D\\u0002\\u0000' ]<\/pre>\n<p>and it is equal to the initial example.<\/p>\n<h2 id=\"conclusion\">Conclusion<\/h2>\n<p>We must be careful when we want to use a function that can take more than one argument, but we want to pass only the value. We have to pass the function as a lambda expression:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&gt; [66, 67, 68].map(v =&gt; String.fromCharCode(v))\r\n[ 'B', 'C', 'D' ]<\/pre>\n<p>or create another function which ensures that only the first argument will be passed to desired function:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\">&gt; const useOnlyValue = f =&gt; v =&gt; f(v);\r\nundefined\r\n&gt; [66, 67, 68].map(useOnlyValue(String.fromCharCode))\r\n[ 'B', 'C', 'D' ]<\/pre>\n","protected":false},"excerpt":{"rendered":"Introduction JavaScript allows for operating on arrays in a functional way, e.g. using filter or map functions. As&hellip;\n","protected":false},"author":54,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[114,176],"class_list":{"0":"post-13604","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-development-design","7":"tag-functional-programming","8":"tag-javascript"},"_links":{"self":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/13604","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/users\/54"}],"replies":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/comments?post=13604"}],"version-history":[{"count":9,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/13604\/revisions"}],"predecessor-version":[{"id":15273,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/13604\/revisions\/15273"}],"wp:attachment":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/media?parent=13604"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/categories?post=13604"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/tags?post=13604"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}