views:

51

answers:

3

I wrote a blog post a while ago detailing how the availability of both primitive and object-wrapped value types in JavaScript (for things such as Number, String and Boolean) causes trouble, including but not limited to type-casting to a boolean (e.g. object-wrapped NaN, "" and false actually type-cast to true).

My question is, with all this confusion and problems, is there any benefit to JavaScript having both types of values for the built-in classes?

Edit: Thanks for the quick answers. I think that the creators of JavaScript intended wrapped natives as a way to make scalar values have child methods, but it clearly backfired, causing more problems.

+5  A: 

According to Douglas Crockford, they are never useful:

Typed wrappers turn out to be completely unnecessary and occasionally confusing. Don't use new Boolean or new Number or new String.

Source: JavaScript: The Good Parts - Appendix B: Bad Parts (Page 114).

He even recommended their deprecation for the 4th Edition of the ECMAScript specification.

Daniel Vassallo
A: 

JavaScript, like many languages, has good parts and bad parts.

This is one of the really really bad parts.

IMHO, there really isn't much benefit, only harm, from typed wrappers.

Our friend Douglas Crockford has been all over this issue, in fact he has been against it from day one. That's all you need to know.

Jacob Relkin
A: 

Douglas Crockford, although being one of the smartest guys out there, is not God - everything he says should not be followed blindly. In fact there is one situation where you would like to prefer wrappers against primitive types - if you would like to pass values around by reference.

Primitive values are always passed around by value and objects by reference. So if for some reason you need to pass numbers by reference then you can do it with the Number objects. You can't actually change the value of the number without loosing the reference (AFAIK) but you can add additional parameters at will as with any object - that's something primitive numbers do not support.

var nr1 = new Number(123),
    nr2 = nr1; // reference to nr1
nr1.name = "number"; //parameter "name" for nr1 is set AFTER the initialization of nr2
alert(nr2.name); // nr2 has the same parameter as nr1
Andris
You can also argue that there is limited scope in passing immutable primitives by reference, because as you said the values cannot be modified. You can add additional fields as in your example, but I wonder if in practice this should be done with **a primitive** type.
Daniel Vassallo
I agree this is not the most practical usage, but my point was to show the actual difference between the primitives and wrapper objects, instead of stating thad Crockford has said something so we must obey. I never use **new Number** by myself as there are better ways to accomplish the same behavior but if someone wants to use it then I can't see any reason why she/he should not.
Andris
@Andris: I think the reason is because they are "completely unnecessary and occasionally confusing". They are unnecessary because as you said, "there are better ways to accomplish the same behavior". And they are occasionally confusing because `b` evaluates to true in this case: `var b = new Boolean(false); if (b) { alert(b) }`
Daniel Vassallo