Valueof() VS. Tostring() in JavaScript

valueOf() vs. toString() in Javascript

The reason why ("x="+x) gives "x=value" and not "x=tostring" is the following. When evaluating "+", javascript first collects primitive values of the operands, and then decides if addition or concatenation should be applied, based on the type of each primitive.

So, this is how you think it works

a + b:
pa = ToPrimitive(a)
if(pa is string)
return concat(pa, ToString(b))
else
return add(pa, ToNumber(b))

and this is what actually happens

a + b:
pa = ToPrimitive(a)
pb = ToPrimitive(b)*
if(pa is string || pb is string)
return concat(ToString(pa), ToString(pb))
else
return add(ToNumber(pa), ToNumber(pb))

That is, toString is applied to the result of valueOf, not to your original object.

For further reference, check out section 11.6.1 The Addition operator ( + ) in the ECMAScript Language Specification.


*When called in string context, ToPrimitive does invoke toString, but this is not the case here, because '+' doesn't enforce any type context.

String.valueOf() vs. Object.toString()

According to the Java documentation, String.valueOf() returns:

if the argument is null, then a string equal to "null"; otherwise, the value of obj.toString() is returned.

So there shouldn't really be a difference except for an additional method invocation.

Also, in the case of Object#toString, if the instance is null, a NullPointerException will be thrown, so arguably, it's less safe.

public static void main(String args[]) {  
String str = null;
System.out.println(String.valueOf(str)); // This will print a String equal to "null"
System.out.println(str.toString()); // This will throw a NullPointerException
}

What's the difference between String(value) vs value.toString()

They are not completely the same, and actually, the String constructor called as a function (your first example), will at the end, call the toString method of the object passed, for example:

var o = { toString: function () { return "foo"; } };
String(o); // "foo"

On the other hand, if an identifier refers to null or undefined, you can't use the toString method, it will give you a TypeError exception:

var value = null;
String(null); // "null"
value.toString(); // TypeError

The String constructor called as a function would be roughly equivalent to:

value + '';

The type conversion rules from Object-to-Primitive are detailed described on the specification, the [[DefaultValue]] internal operation.

Briefly summarized, when converting from Object-to-String, the following steps are taken:

  1. If available, execute the toString method.

    • If the result is a primitive, return result, else go to Step 2.
  2. If available, execute the valueOf method.

    • If the result is a primitive, return result, else go to Step 3.
  3. Throw TypeError.

Given the above rules, we can make an example of the semantics involved:

var o = {
toString: function () { return "foo"; },
valueOf: function () { return "bar"; }
};

String(o); // "foo"

// Make the toString method unavailable:
o.toString = null;

String(o); // "bar"

// Also make the valueOf method unavailable:
o.valueOf = null;

try {
String(o);
} catch (e) {
alert(e); // TypeError
}

If you want to know more about this mechanism I would recommend looking at the ToPrimitive and the ToString internal operations.

I also recommend reading this article:

  • Object-to-Primitive Conversions in JavaScript

Join() vs toString() vs valueOf() in Javascript

toString is a method that you can find not only in Arrays, but in every object.

join allows you to convert every element of the Array object in to a string, and joining together using a separator. It behaves just like toString for Arrays, but you can also specify the separator:

var classes = ["first", "second"];
classes.join(" "); // "first second"

toString() in JavaScript: why does toString() still get called since a valueOf() prototype for type conversion of object to number

Since +obj requires a number, shouldn't it use the valueOf() prototype for type conversion which returns the object.

It actually does call the valueOf method. But since - as you say - it returns an object, not a primitive value, it is found useless. Then, the alternative is called: toString(), which does return a primitive value that is subsequently cast to a number.

You can try

const obj1 = {    valueOf() { console.log("valueOf 1"); return this; },    toString() { console.log("toString 1"); return "1"; },};console.log(+obj1);
const obj2 = { valueOf() { console.log("valueOf 2"); return 2; }, toString() { console.log("toString 2"); return "2"; },};console.log(+obj2);

Does valueOf always override toString in javascript?

The + operator on Date objects uses toString not valueOf. Also if valueOf returns a non-primitive value then the toString method is called next. (JavaScript - The definitive guide, section 3.14) Using your example:

var result = "4" + {
toString: function () {
return "4";
},
valueOf: function () {
return this; // returning an object, not a primitive
}
};

Result is now 44.

Application area of toString() and valueOf() method

toString converts a value to a string, valueOf converts it to a number. Exactly which one is called depends on the context in which you're asking.

If javascript is expecting a string or trying to coerce the object to a string, it will use toString. If it is expecting a number it will use valueOf.

the exception to this rule is that when a value has both a toString and a valueOf, it always calls valueOf.

var x = {
toString: function(){
return "x";
},

valueOf: function(){
return 2;
}

}

alert("String :"+x); //2

alert("Number :"+(0+x)); //2

fiddle: http://jsfiddle.net/DsGKf/

So be careful about defining valueOf on things that you want to have act as strings.

Difference between value.toString and value.toString()

value.toString() -> It will convert any value to string and return that value.

value.toString -> It will work as a primitive value and it will create an object wrapper. That's why it will not give any error or warning instead it will return a reference to the toString method.

So in short value.toSting() will return a string and value.toString will return a reference to the toString method.

About javascript function valueOf\toString and 'curry' function behaved differently in Chrome,Firefox and node enviroment

At first you can beautify the whole code a bit:

function add(..arr){
function fun(...args){
arr.push(...args);
return fun
}

fun.toString = function(){
return arr.reduce((total, num) => total + num)
};
return fun;
}

And as you noticed correctly, logging a function is completely up to the environment. Firefox and Node return the code of the function, while Chrome does sth like:

out( "f" + add.toString())

so our toString function gets called and something is logged. To have a consistent behaviour between the different environments we could call toString explicitly:

console.log(add(1)(2)(3).toString());

This can be inferred:

console.log("" + add(1)(2));


Related Topics



Leave a reply



Submit