3

Fun with valueOf in javascript

 3 years ago
source link: https://blog.klipse.tech/javascript/2016/09/21/valueOf-js.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Fun with valueOf in javascript

Sep 21, 2016 • Yehonathan Sharvit

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…

good parts

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?

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

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:

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

Calling sum another time with the same argument:

xxxxxxxxxx
sum(arr)
xxxxxxxxxx
1.4054973168054172

But not the same result.

And once again, for the fun:

xxxxxxxxxx
sum(arr)
xxxxxxxxxx
1.7983368576777774

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

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

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

xxxxxxxxxx
sum(arr_with_get)
xxxxxxxxxx
2.5365443062998594
xxxxxxxxxx
sum(arr_with_get)
xxxxxxxxxx
2.0746291146868607

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:

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

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?

If you enjoy this kind of interactive articles would you consider a (small) donation💸 on Patreon or at least giving a star⭐ for the Klispe repo on Github?

to stay up-to-date with the coolest interactive articles around the world.

Discover more cool interactive articles about javascript, clojure[script], python, ruby, scheme, c++ and even brainfuck!

Give Klipse a Github star to express how much you appreciate Code Interactivity.

Subscribe to the Klipse newsletter:

Feel free to email me [email protected] for getting practical tips and tricks in writing your first interactive blog post.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK