Fun with valueOf in javascript
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.
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…
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?
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.
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK