1

let obj = {
  valueOf() {
    return "2";
  }
};

alert(obj);

I thought in the absence of toString() the valueOf() will be called when a string is expected.

Code Maniac
  • 37,143
  • 5
  • 39
  • 60
Israel
  • 77
  • 7
  • 2
    Why did you think alert would require a primitive? `+obj` gives `2`, as expected – jonrsharpe Mar 29 '20 at 17:28
  • doesn't alert() always convert it's argument to a string? – Israel Mar 29 '20 at 17:34
  • Yes, but that's different than a primitive value - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/valueOf – jonrsharpe Mar 29 '20 at 17:35
  • 1
    @jonrsharpe well actually i do see it does call valueOf if it doesn't find toString method, look at my answer. since here we are not creating a pure object so it find toString on prototype and won't call valueOf. – Code Maniac Mar 29 '20 at 17:39
  • Thanks for the link. I read in it that when a string value is required, toString() will be called which is the case with alert(). But since there is no toString() shouldn't it fall back on valueOf()? – Israel Mar 29 '20 at 17:43
  • Their point is that there *is* a toString, the one returning `"[object Object]"`. – jonrsharpe Mar 29 '20 at 17:48
  • So my error was I thought toString() was absent but isn't. Thank you – Israel Mar 29 '20 at 18:01

1 Answers1

2

This does not call because this find toString in prototype chain, if we create a object without any prototype it will call

let obj = Object.create(null)

obj.valueOf =
  function() {
    return "2";
  }

alert(obj);
Code Maniac
  • 37,143
  • 5
  • 39
  • 60
  • Okay I know that every object has toString() as [object Object] even if I didn't add it as a property in the object. So what you're saying is if I call Object.create(null) it removes the toString() prototype? – Israel Mar 29 '20 at 17:48
  • @Israel yes this is used to setup prototype to null, or in normally it is called a pure object – Code Maniac Mar 29 '20 at 17:52
  • If that is the case then why does toString() get called if I replace the valueOf() in my question with toString() and I change the alert() to statement that requires a number not a string – Israel Mar 29 '20 at 17:52
  • @Israel it searches in prototype chain for toString so if you object has toString it just calls that function, if not then it searches down the prototype if found call that function if not then it calls valueOf – Code Maniac Mar 29 '20 at 17:54
  • Okay, I understand. Thank you – Israel Mar 29 '20 at 18:01
  • Then what about this – Israel Mar 29 '20 at 18:02
  • If I replace the valueOf() in the code with toString(). And I replace the alert() with a statement that requires a number. Why does the toString() still get called if there is a prototype already for valueOf() that returns the object itself – Israel Mar 29 '20 at 18:05
  • @Israel can you post example of statement you're talking about, the best is you can use `[Symbol.toPrimitive]` on object to see in what hint the object is getting converted. – Code Maniac Mar 29 '20 at 18:11
  • Okay. I've posted a new question on that. I am aware of the [Symbol.toPrimitive]. I just want to understand prototypes better. Thanks for your help – Israel Mar 29 '20 at 18:25