Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does valueOf always override toString in javascript?

Is there any expression where by an object's toString method is implicitly called overriding its valueOf method?

In the examples below, valueOf is always called implicitly (overriding toString).

"4" + {
    toString: function () {
        return "4";
    },
    valueOf: function () {
        return 6;
    }
};    // => "46", was expecting "44"

4 + {
    toString: function () {
        return "6";
    },
    valueOf: function () {
        return 4;
    }
};    // => 8

4 + {
    toString: function () {
        return 6;
    },
    valueOf: function() {
        return "4";
    }
};    // => "44"

i.e.:

Can we write an expression where by toString is implicitly called over valueOf (i.e without explicitly calling toString)?

like image 997
cmutex Avatar asked Jan 02 '14 22:01

cmutex


People also ask

What is the difference between toString () and valueOf () in JavaScript?

If the hint is String , then toString is used before valueOf . But, if the hint is Number , then valueOf will be used first. Note that if only one is present, or it returns a non-primitive, it will usually call the other as the second choice.

Can we override toString method in JavaScript?

toString() ). This method is inherited by every object descended from Object , but can be overridden by descendant objects (for example, Number. prototype. toString() ).

Is toString always override?

So just because a data class defines a toString doesn't mean you shouldn't override it.

What happens if we don't override toString?

So, whenever you use or print a reference variable of type in which toString() method is not overrided, you will get an output like above. You will not get what the object actually has in it. There will be no information about state or properties of an object.


1 Answers

Is there any expression where by an object's toString method is implicitly called overriding its valueOf method?

Yes, that does happen whenever the abstract ToString operation is applied on an object, using the DefaultValue procedure with .toString() before .valueOf().

However, in your examples you have only used the addition operator which is like an exception from the standard behaviour. Since it does not only concatenate strings, but also sums numbers, it always uses valueOf on both operands before checking whether they're strings. See the note 1:

No hint is provided in the calls to ToPrimitive in steps 5 and 6. All native ECMAScript objects except Date objects handle the absence of a hint as if the hint Number were given; Date objects handle the absence of a hint as if the hint String were given. Host objects may handle the absence of a hint in some other manner.

So which operations do implicitly use the ToString instead of a hint-less ToPrimitive? Here are a few examples:

  • Everything about property names: The in operator, bracket notation, Object.getOwnPropertyDescriptor, Object.defineProperty, hasOwnProperty, …
  • Functions expecting strings as arguments: parseInt, parseFloat, encodeURI[Component], decodeURI[Component], [un]escape, Array::join, String::[last]indexOf, RegExp::exec
  • The Function constructor
  • The Array::sort algorithm's default compare function
  • The String constructor and String methods when casting the this object to a string
  • The RegExp constructor
  • The Error constructors
  • Lots of other functions not specified by EcmaScript but in the DOM or somewhere else, like alert, XMlHTTPRequest::open, querySelector, …
like image 119
Bergi Avatar answered Oct 16 '22 05:10

Bergi