Wednesday, January 11, 2017 II


In the previous blog-post titled  I proposed  that Functions in JavaScript should have  the method "map()" like Arrays do, allowing you to process each element with a function instead of the longer and more complicated for-in -statement.  is called like: The proposed

Apart from the syntactic difference of reversing the roles of argument and recipient, also removes all undefined elements from the result. That makes it suitable for not only transforming every element of an array, but also for filtering out some of them.

In this  follow-up I present one more feature differentiating from Its ability to iterate over non-Array Objects.



The new behavior in version-2 is exemplified by the following few lines of code The function ok() is my simple ad hoc assert-utility which  throws an error if called with anything untrue.
 var o  = {x:1, y:2, z:3};
 var o2 = (o);

 ok (o2.x === 1         );
 ok (o2.y === undefined );
 ok (o2.z === 3         );

 function odd (n)
 { if (n % 2) {return n}

 function ok (b)
 { if (!b)  
   { throw "assert failed";


You might write a function that takes as argument an object with fields x, y, z whose values must be numbers, representing a point in three-dimensional space. You then might want to write a short routine that checks that x, y and z really are numbers, all of them. 

Assuming your argument is named 'coordinates' you could write checker-code like:

  // var coordinates = {x:1, y:2, z:3};
  for (var p in  coordinates)
  { assertIsNumber (coordinates, p); 

But aren't you tired of writing for-loops already?  

Having installed, you can write the equivalent of the above as:

  // var coordinates = {x:1, y:2, z:3}; (coordinates);

In both cases the checker-function could be defined as:

function assertIsNumber (n)
{  if (typeof n === "number") return;
   throw "Not a number: " + n;


Below you see the JavaScript code for installation, tests, and implementation of this new improved version:

// ------------------  cut here -------------------------

// 1. INSTALLATION: = map2;

// 2. TESTS:
test_map2 (); 

function test_map2 ()
 // 2.A:  FOR ARRAYS:
 var a  = [1,2,3];
 var a2 =;

 ok (a2[0] === 1);
 ok (a2[1] === 3);
 ok (a2.length  === 2);

 // 2.B:  FOR OBJECTS:
 var o  = {x:1, y:2, z:3};
 var o2 = (o);

 ok (o2.x === 1        );
 ok (o2.y === undefined);
 ok (o2.z === 3        );

 var coordinates =  {x:1, y:2, z:3}; (coordinates);

 // Next would fail because y-value is not a number:
 // ({x:1, y:"s"} );

 return;  // from test_map2()

 function ok (b)
 { if (!b)  
   { throw "assert failed";

 function assertIsNumber (n)
 { if (typeof n === "number") 
{ return n;
   throw "not a number: " + n;


function map2 (objectOrArray, thisArg)
  var resultA, resultB;
  if (objectOrArray.constructor === Array)
  { return (this, objectOrArray, thisArg);
  return (this, objectOrArray, thisArg);

    function map2_object (anObject, thisArg)
    { var result  = new anObject.constructor(); 
      for (var p in anObject)
      { var v = this (anObject[p], p, anObject) ;
        if (v !== undefined)
        { result  [p] = v;
      return result;
    } // end map2_object()

    function map2_array (anArray, thisArg)
    { resultA = []  (anArray, this, thisArg);
      resultB = [];
      for (var j=0; j < resultA.length; j++)
      { var e = resultA[j];
        if (e !== undefined)
{ resultB . push(e);  
return resultB;
     } // end map2_array()

   } // end map2()

// ------------------  cut here -------------------------


Copy the code from Section 3. to the start of your JavaScript-file. After that you can call  'map()' on any function with any []  OR any {} as argument.

What name to use to install this function as a method in Function.prototype is of course up to you. In my own projects I've chosen to install it as 'map' because of  its close proximity in  behavior to the already standard


Iterating over non-arrays is a frequent task in JavaScript. The for-in statement which does it however quickly becomes tedious to write, again and again. JavaScript does have the which makes it simpler to iterate over Arrays. can not be used for non-arrays because it is not! But with you can perform the more general task of calling map() on a Function, to process Objects and Arrays alike.

Yes, we are aware there is also, but that is not quite the same as For one thing it doesn't remove undefined values and it only works on instances of Map. And it returns undefined.

For more about, see my previous blog-post

Copyright © 2017 Panu Viljamaa. All rights reserved unless otherwise noted.
Reuse of source-code in this blog-post is allowed under the terms of 
Creative Commons Attribution 4.0 International (CC BY 4.0) -license 

No comments:

Post a Comment