What is the difference between "new Number(...)" and "Number(...)" in JavaScript? - javascript

In Javascript, one of the reliable ways to convert a string to a number is the Number constructor:
var x = Number('09'); // 9, because it defaults to decimal
Inspired by this question, I started wondering — what is the difference between the above and:
var x =new Number('09');
Number certainly looks better, but it seems like a slightly inappropriate use of a constructor. Are there any side effects or any difference to using it without the new? If there is no difference, why not, and what is the purpose of new?

In the first case, you are using the Number Constructor Called as a Function, as described in the Specification, that will simply perform a type conversion, returning you a Number primitive.
In the second case, you are using the Number Constructor to make a Number object:
var x = Number('09');
typeof x; // 'number'
var x = new Number('09');
typeof x; // 'object'
Number('1') === new Number('1'); // false
The difference may be subtle, but I think it's important to notice how wrapper objects act on primitive values.

Number returns a primitive number value. Yeah, it's a bit odd that you can use a constructor function as a plain function too, but that's just how JavaScript is defined. Most of the language built-in types have weird and inconsistent extra features like this thrown in.
new Number constructs an explicit boxed Number object. The difference:
typeof Number(1) // number
typeof new Number(1) // object
In contrast to Java's boxed primitive classes, in JavaScript explicit Number objects are of absolutely no use.
I wouldn't bother with either use of Number. If you want to be explicit, use parseFloat('09'); if you want to be terse, use +'09'; if you want to allow only integers, use parseInt('09', 10).

SpiderMonkey-1.7.0:
js> typeof new Number('09');
object
js> typeof Number('09');
number

Number (without new) doesn't seem to result exactly in a primitive. In the following example the anyMethod() is called (if in the Number prototype).
Number(3).anyMethod()
Whereas
3.anyMethod()
will not work.

Related

Creating Numbers and Strings with Object()

I would love a clear explanation as to better understand what's going on here?
I can create what look like primitive types with Object. It looks like a number but not quite for a string. I was under the impression that Object() was used to create all objects in js (ie of type object) but not primitive types, like number, string boolean.
There are times when a primitive type (Boolean, Number or String) needs to be converted to object albeit temporarily.
Look at this example:
var str = 'javascript';
str = str.substring(4);// You get "script" but how?
How can you call a function on something that is not an object? The reason is that primitive value is wrapped into Object(String) on which substring() method is defined. If it was not done, you would not be able to call the method in the primitive type. Such wrappers are called Primitive Wrappers.
Also, it doesn't mean that str has now become an object. So, if you said:
str.myProp = 10;
and then console.log(str.myProp);//You would get undefined
The difference between a reference type and a primitive wrapper object is lifetime. Primitive wrappers die soon.
So you can think of
var str = 'javascript';
str = str.substring(4);// You get "script" but how?
As these lines:
var str = new String(“javascript”);
str = str.substring(4);
str = null;
Now coming to what you are doing:
number = Object(5);
Here you are wrapping a number primitive into an object. It is as if you had written:
number = new Number(5);
Here, Object(5) is behaving as a factory and depending on the type of the input(number, string), it gives back object by wrapping primitive value into it.
So, Object(5) is equivalent to new Number(5) and Object('test') is as if saying new String('test').
Hope this helps!
The notion of primitives and objects is slightly implementation dependent. But you can think of it like this:
Primitives are not objects. They have their own special semantics, such as the string "hello" is the same no matter how many times you create one. However, the object new String("hello") should return a new string every time.
In many implementations, there is auto-boxing and unboxing of primitives when they need to act like objects and vice-versa. I would suggest reading this question for more details: What is the difference between string literals and String objects in JavaScript?
You can use Object.prototype.valueOf() to get [[PrimitiveValue]] 5 or "test".
var number = new Object(5);
var aString = new Object("test");
console.log(number.valueOf(), aString.valueOf());
5.toString();
As you can see Number is an object. But number is not. In some cases primitives are wrapped by objects to implement object like behaviours...
5 // primitive type
Object(5) // wrapper of that primitive type
5.toString() === Object(5).toString() //...

Why is new Number(8) not exactly equal to 8?

alert returns false instead of true? as type is Number for both x and y and as per documentation of === its a strict compare which checks type along with value.
var x=8;
var y=new Number(8);
alert(typeof x);
alert(y===x);//false
PS : new to JavaScript still understanding the base concepts.
The primitive types Boolean, Number and String, each have a corresponding object representation, which can be created via new Boolean, new String, etc. As I already hinted at, those return objects. An Object is a different data type than a Number, so strict comparison will return false.
However, those constructors are not widely used, because, as you found out, they don't play well with primitives. A Number object that encapsulates the same value as a primitive number value is not (strictly) equal to said primitive value.
What you might see more often is the use of the Number function without new. If called without new, Number simply performs type conversion, to a primitive number value.
So why do we have Number, String and Boolean objects at all?
It turns out you are using such objects all the time without (probably) knowing, e.g. when you do
"primitive".substring(0, 5)
In JavaScript, only objects can have properties. Primitive values cannot have properties. And yet you can call the substring method as if it was a property of the value. That's because JavaScript does something called auto-boxing. When you are trying to use a primitive values like an object (e.g. by accessing a property), JavaScript internally converts the primitive temporarily to its equivalent object version.
That is because when instantiating using new the type is object even if that object's name is Number.
typeof y === "object"
Y is an object not a number. The new keyword references to objects. So y is a number object with the value 8.
Try alert(typeof y);
First off, alert does always return undefined. But it prints stuff on screen. console.log gives you more detailed and colorful info though.
This problem has two parts. First one is that numbers are normally not Number instance. The second is that two objects (two instances) of any kind are never exactly equal:
{}=={} // false
Not Number problem
Now to the Number issue. Although all numbers in JavaScript are technically a Number, javascript does not treat them like that and they are not number instance. This is something I don't like very much, but it's what it is. If you create number by instance, it behaves as non-object value:
5 instanceof Number //false
typeof 5 // "number"
Creating number with Number constructor creates an object, that acts as a Number:
new Number(5) instanceof Number //true
typeof new Number(5) // "object"
It should be noted that this object is actually not very special. You can make your own number class:
function MyNumber(val) {
this.number = 1*val||0;
}
MyNumber.prototype.valueOf = function() {
return this.number;
}
This will work just as Number object does. Of course, just as Number object, this is lost when you do a math operation:
typeof (MyNumber(6)+MyNumber(4)) // "number"
Two object instances are never exactly equal
This is actually useful feature. But it betrays you here:
new Number(5)===new Number(5) //false
Number instance will never be exactly equal to anything but itself.
when you make var y=new Number(8); it becomes a object not a number and because of that === fails to compare both as same.
var x=8;
var y=new Number(8);
alert(typeof x);//number
alert(typeof y);//object
alert(y===x);//false

What is the difference between String and new String? [duplicate]

Taken from MDN
String literals (denoted by double or single quotes) and strings
returned from String calls in a non-constructor context (i.e., without
using the new keyword) are primitive strings. JavaScript automatically
converts primitives to String objects, so that it's possible to use
String object methods for primitive strings. In contexts where a
method is to be invoked on a primitive string or a property lookup
occurs, JavaScript will automatically wrap the string primitive and
call the method or perform the property lookup.
So, I thought (logically) operations (method calls) on string primitives should be slower than operations on string Objects because any string primitive is converted to string Object (extra work) before the method being applied on the string.
But in this test case, the result is opposite. The code block-1 runs faster than the code block-2, both code blocks are given below:
code block-1 :
var s = '0123456789';
for (var i = 0; i < s.length; i++) {
s.charAt(i);
}
code block-2 :
var s = new String('0123456789');
for (var i = 0; i < s.length; i++) {
s.charAt(i);
}
The results varies in browsers but the code block-1 is always faster. Can anyone please explain this, why the code block-1 is faster than code block-2.
JavaScript has two main type categories, primitives and objects.
var s = 'test';
var ss = new String('test');
The single quote/double quote patterns are identical in terms of functionality. That aside, the behaviour you are trying to name is called auto-boxing. So what actually happens is that a primitive is converted to its wrapper type when a method of the wrapper type is invoked. Put simple:
var s = 'test';
Is a primitive data type. It has no methods, it is nothing more than a pointer to a raw data memory reference, which explains the much faster random access speed.
So what happens when you do s.charAt(i) for instance?
Since s is not an instance of String, JavaScript will auto-box s, which has typeof string to its wrapper type, String, with typeof object or more precisely s.valueOf(s).prototype.toString.call = [object String].
The auto-boxing behaviour casts s back and forth to its wrapper type as needed, but the standard operations are incredibly fast since you are dealing with a simpler data type. However auto-boxing and Object.prototype.valueOf have different effects.
If you want to force the auto-boxing or to cast a primitive to its wrapper type, you can use Object.prototype.valueOf, but the behaviour is different. Based on a wide variety of test scenarios auto-boxing only applies the 'required' methods, without altering the primitive nature of the variable. Which is why you get better speed.
This is rather implementation-dependent, but I'll take a shot. I'll exemplify with V8 but I assume other engines use similar approaches.
A string primitive is parsed to a v8::String object. Hence, methods can be invoked directly on it as mentioned by jfriend00.
A String object, in the other hand, is parsed to a v8::StringObject which extends Object and, apart from being a full fledged object, serves as a wrapper for v8::String.
Now it is only logical, a call to new String('').method() has to unbox this v8::StringObject's v8::String before executing the method, hence it is slower.
In many other languages, primitive values do not have methods.
The way MDN puts it seems to be the simplest way to explain how primitives' auto-boxing works (as also mentioned in flav's answer), that is, how JavaScript's primitive-y values can invoke methods.
However, a smart engine will not convert a string primitive-y to String object every time you need to call a method. This is also informatively mentioned in the Annotated ES5 spec. with regard to resolving properties (and "methods"¹) of primitive values:
NOTE The object that may be created in step 1 is not accessible outside of the above method. An implementation might choose to avoid the actual creation of the object. [...]
At very low level, Strings are most often implemented as immutable scalar values. Example wrapper structure:
StringObject > String (> ...) > char[]
The more far you're from the primitive, the longer it will take to get to it. In practice, String primitives are much more frequent than StringObjects, hence it is not a surprise for engines to add methods to the String primitives' corresponding (interpreted) objects' Class instead of converting back and forth between String and StringObject as MDN's explanation suggests.
¹ In JavaScript, "method" is just a naming convention for a property which resolves to a value of type function.
In case of string literal we cannot assign properties
var x = "hello" ;
x.y = "world";
console.log(x.y); // this will print undefined
Whereas in case of String Object we can assign properties
var x = new String("hello");
x.y = "world";
console.log(x.y); // this will print world
String Literal:
String literals are immutable, which means, once they are created, their state can't be changed, which also makes them thread safe.
var a = 's';
var b = 's';
a==b result will be 'true' both string refer's same object.
String Object:
Here, two different objects are created, and they have different references:
var a = new String("s");
var b = new String("s");
a==b result will be false, because they have different references.
If you use new, you're explicitly stating that you want to create an instance of an Object. Therefore, new String is producing an Object wrapping the String primitive, which means any action on it involves an extra layer of work.
typeof new String(); // "object"
typeof ''; // "string"
As they are of different types, your JavaScript interpreter may also optimise them differently, as mentioned in comments.
When you declare:
var s = '0123456789';
you create a string primitive. That string primitive has methods that let you call methods on it without converting the primitive to a first class object. So your supposition that this would be slower because the string has to be converted to an object is not correct. It does not have to be converted to an object. The primitive itself can invoke the methods.
Converting it to an full-blown object (which allows you to add new properties to it) is an extra step and does not make the string oeprations faster (in fact your test shows that it makes them slower).
I can see that this question has been resolved long ago, there is another subtle distinction between string literals and string objects, as nobody seems to have touched on it, I thought I'd just write it for completeness.
Basically another distinction between the two is when using eval. eval('1 + 1') gives 2, whereas eval(new String('1 + 1')) gives '1 + 1', so if certain block of code can be executed both 'normally' or with eval, it could lead to weird results
The existence of an object has little to do with the actual behaviour of a String in ECMAScript/JavaScript engines as the root scope will simply contain function objects for this. So the charAt(int) function in case of a string literal will be searched and executed.
With a real object you add one more layer where the charAt(int) method also are searched on the object itself before the standard behaviour kicks in (same as above). Apparently there is a surprisingly large amount of work done in this case.
BTW I don't think that primitives are actually converted into Objects but the script engine will simply mark this variable as string type and therefore it can find all provided functions for it so it looks like you invoke an object. Don't forget this is a script runtime which works on different principles than an OO runtime.
The biggest difference between a string primitive and a string object is that objects must follow this rule for the == operator:
An expression comparing Objects is only true if the operands reference
the same Object.
So, whereas string primitives have a convenient == that compares the value, you're out of luck when it comes to making any other immutable object type (including a string object) behave like a value type.
"hello" == "hello"
-> true
new String("hello") == new String("hello") // beware!
-> false
(Others have noted that a string object is technically mutable because you can add properties to it. But it's not clear what that's useful for; the string value itself is not mutable.)
The code is optimized before running by the javascript engine.
In general, micro benchmarks can be misleading because compilers and interpreters rearrange, modify, remove and perform other tricks on parts of your code to make it run faster.
In other words, the written code tells what is the goal but the compiler and/or runtime will decide how to achieve that goal.
Block 1 is faster mainly because of:
var s = '0123456789'; is always faster than
var s = new String('0123456789');
because of the overhead of object creation.
The loop portion is not the one causing the slowdown because the chartAt() can be inlined by the interpreter.
Try removing the loop and rerun the test, you will see the speed ratio will be the same as if the loop were not removed. In other words, for these tests, the loop blocks at execution time have exactly the same bytecode/machine code.
For these types of micro benchmarks, looking at the bytecode or machine code wil provide a clearer picture.
we can define String in 3-ways
var a = "first way";
var b = String("second way");
var c = new String("third way");
// also we can create using
4. var d = a + '';
Check the type of the strings created using typeof operator
typeof a // "string"
typeof b // "string"
typeof c // "object"
when you compare a and b var
a==b ( // yes)
when you compare String object
var StringObj = new String("third way")
var StringObj2 = new String("third way")
StringObj == StringObj2 // no result will be false, because they have different references
In Javascript, primitive data types such is string is a non-composite building block. This means that they are just values, nothing more:
let a = "string value";
By default there is no built-in methods like toUpperCase, toLowerCase etc...
But, if you try to write:
console.log( a.toUpperCase() ); or console.log( a.toLowerCase() );
This will not throw any error, instead they will work as they should.
What happened ?
Well, when you try to access a property of a string a Javascript coerces string to an object by new String(a); known as wrapper object.
This process is linked to concept called function constructors in Javascript, where functions are used to create new objects.
When you type new String('String value'); here String is function constructor, which takes an argument and creates an empty object inside the function scope, this empty object is assigned to this and in this case, String supplies all those known built in functions we mentioned before. and as soon as operation is completed, for example do uppercase operation, wrapper object is discarded.
To prove that, let's do this:
let justString = 'Hello From String Value';
justString.addNewProperty = 'Added New Property';
console.log( justString );
Here output will be undefined. Why ?
In this case Javascript creates wrapper String object, sets new property addNewProperty and discards the wrapper object immediately. this is why you get undefined. Pseudo code would be look like this:
let justString = 'Hello From String Value';
let wrapperObject = new String( justString );
wrapperObject.addNewProperty = 'Added New Property'; //Do operation and discard

JavaScript primitive types and corresponding objects

In JavaScript not every data is an object. There exist a few primitive types, like strings, numbers and Boolean which are not objects. For each of these types there exists a constructor which outputs an object with similar behaviour: Number, String and Boolean. To confuse matters, one actually can call methods on primitive types - they will be converted to the corresponding objects during this operation, and then converted back. For instance one can do
var a = 4.1324;
a.toFixed(1) // Outputs 4.1
Yet, if you try to compare primitive types and objects with strict equality, the difference shows up
var a = new Number(4);
var b = 4;
a === b; // False!!!
typeof a; // 'object'
typeof b; // 'number'
Actually of one tries to compare objects, they turn out to be different anyway:
var a = new Number(4);
var b = new Number(4);
a === b; // False!!!
(From a conceptual point of view I sort of understand the distinction. Objects can have additional properties, hence they should not compare to equal unless they are actually the same. So if we want to have 4 === 4 we need to use a type which is not an object. But this dilemma is faced by any sufficiently dynamic programming language, yet JavaScript is the only one I know where there are two types - one objectful and one not - for numbers or strings.)
What is the advantage of keeping two separate representations for numbers, strings and Booleans? In what context could one need the distinction between primitive types and objects?
What is the advantage of keeping two
separate representations for numbers,
strings and Booleans?
Performance
In what context could one need the
distinction between primitive types
and objects?
Coercion comes to mind. 0 == false while new Number(0) != false
So for instance:
var a = new Boolean(false);
if(a) {
// This code runs
}
but
var a = false;
if(a) {
// This code never runs
}
You can read more about coercion here: JavaScript Coercion Demystified
What is the advantage of keeping two separate representations?
As you point out, you can call methods on unboxed values too (a.toFixed(1)). But that does cause a conversion. In other words, an instantiation of a new boxed object (probably) every time you call such a method.
So there is a performance penalty right there. If you explicitly create a boxed Number and then call its methods, no further instances need to be created.
So I think the reason for having both is much historical. JavaScript started out as a simple interpreted language, meaning performance was bad, meaning any (simple) way they could increase performance was important, such as making numbers and strings primitive by default.
Java has boxed vs. unboxed values as well.

Why does attempting to assign a value to a simple type's property in Javascript not throw an exception?

Simple types in Javascript are immutable and are not keyed collections like Objects. Why does the following code just return the value of the assignment without complaining?
var foo = 'bar';
foo.newProperty = 'blaha';
The second statement just returns 'blaha'. However if you now call foo.newProperty you naturally get undefined because simple types are not hashes. So the question is shouldn't the attempt at property assignment throw an exception the same way that you get a TypeError when trying to replace a value in a tuple in Python. Or is there some obscure feature of the syntax that makes foo.newProperty evaluate to something unexpected?
There is an obscure feature of the syntax that makes foo.newProperty work. :-) Strings and numbers can be either primitives or objects, and the interpreter will automagically convert from a primitive to an object (and vice-versa) if it sees the need to.
var foo = 'bar'; // `foo` is a primitive
alert(typeof foo); // alerts "string"
var foo2 = new String('bar'); // `foo2` is an object
alert(typeof foo2); // alerts "object"
The reason that adding a property to a primitive works, but then seems later not to have worked, is that the conversion is only for the purposes of the expression. So if I do:
foo.newProperty = 'blaha';
The primitive string value is retrieved from the foo variable and then converted from a primitive to an object for the expression, but only for the expression (we haven't assigned a new value to the variable foo, after all, it's just that the value retrieved from foo for the expression has been changed to make the expression work). If we wanted to ensure that foo referred to a String object, we'd have to do that on purpose:
foo = new String(foo);
foo.newProperty = 'blaha';
This automagic conversion is covered (a bit) in Section 9 ("Type Conversion and Testing") and Section 11.2.1 ("Property Accessors") in the spec, albeit in the usual awkward specification-speak style. :-)
Re your question "...is there a good reason for this automagic wrapping?" below: Oh yes. This automatic promotion from primitive to object is pretty important. For instance:
var foo = "bar";
alert(foo.length);
Primitives don't have properties, so if there weren't any auto-promotion, the second line above would fail. (Naturally, an implementation is free to optimize such that actual object creation isn't required, as long as it behaves as the spec dictates externally.) Similarly:
var foo = "bar";
alert(foo.indexOf('a')); // alerts 1
Primitives aren't objects, and so they don't have a prototype chain, so where does that indexOf property come from? And of course, the answer is that the primitive is promoted to a String instance, and String.prototype has indexOf.
More dramatically:
alert((4).toFixed(2)); // alerts "4.00"
Since numbers are also promoted as needed, it's perfectly acceptable to do that. You have to use the parens — e.g., the (4) rather than just 4 — to satisfy the grammar (since the . in a literal number is a decimal point rather than a property accessor), although if you wanted to be really esoteric you could use 4['toFixed'](2). I wouldn't. :-)

Categories

Resources