Javascript is a language full of surprises: there are the good parts and the bad parts . Today, I discovered valueOf. I’ll let you decide to what parts of javascript valueOf belongs…

A pure function that is not pure

The following interactive code snippet is based on Is Your Javascript function actually pure?.

Have a look at this (simple?) javascript function and ask yourself whether it is a pure function or not.

Does the following function always returns the same result given the same argument?

function sum(arr) { var z = 0; for (var i = 0; i < arr.length; i++) { z += arr[i]; } return z; }

If you are like the majority of javascript developers, you probably think that the answer is: YES .

But the correct answer is: NO .

Here is the proof:

var arr = [{}, {}, {}]; arr[0].valueOf = arr[1].valueOf = arr[2].valueOf = Math.random; sum(arr)

Calling sum another time with the same argument:

sum(arr)

But not the same result.

And once again, for the fun:

sum(arr)

Someone wrote in Reddit that we can also hack the sum function using Object.defineProperty . Like this:

arr_with_get = [0,0,0]; arr_with_get.forEach(function(o, i, a) { Object.defineProperty(a, i, {get:Math.random}); });

And indeed, sum returns different results with the same input:

sum(arr_with_get)

sum(arr_with_get)

An impossible assertion that is true

Another weird example is shown in Object.prototype.valueOf, Coercion, and Comparison Hackery in JavaScript.

We are going to provide an object that will make the following (impossible) assertion be true

( mysteryObject < 1 ) && ( mysteryObject > 1 )

Here is the interactive code snippet for mysteryObject :

var mysteryObject = (function() { var cachedValue = -2; return { valueOf: function() { return cachedValue += 2; } }; })(); (mysteryObject < 1) && (mysteryObject > 1)

Conclusion

Did you like it? Does valueOf belong to the good parts or to the bad parts of javascript?

What do you think about the interactive code snippets powered by KLIPSE?