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

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

Related

why 3==new Number(3) gives true why?

I follow the below links
Why should you not use Number as a constructor?
Question about object.method in JavaScript
why 3==new Number(3) gives true why ??
3== new Number(3) // true
As of I know == only check the value.but new Number(3) is a object how it value become 3.
how new Number(3) value is 3
Abstract Equality Comparison, or x == y, does, on step 10:
If Type(x) is either String, Number, BigInt, or Symbol and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
So the evaluation of
3 == new Number(3)
becomes
3 == Number(new Number(3))
Although new Number(3) results in a (number) object, it then gets cast to its primitive value (a plain non-object number), and 3 == 3 is true.
It's giving true because of coercion in javascript.
Javascript will convert object to number implicitly while evaluating equality operation.
While it's true that == coerces the data type for comparison to be done, your basic question of:
As of I know == only check the value.but new Number(3) is a object how
it value become 3.
has a different answer. All objects in JavaScript inherit from Object.prototype and that object has a valueOf() and a toString() method. These methods are automatically used by the JavaScript runtime when the fundamental (primitive) value or string representation of that value are required. So in this case, although new Number(3) returns an object, the valueOf() method is implicitly being called to return the value of 3 for the rest of the expression to work with.
From the MDN link above:
JavaScript calls the valueOf method to convert an object to a
primitive value. You rarely need to invoke the valueOf method
yourself; JavaScript automatically invokes it when encountering an
object where a primitive value is expected.
These methods are automatically called when needed, as I said, but you can call them as well on any object:
// There will be no implicit call for .valueOf here because there is no
// context for the JS runtime to know what you want to do with the object.
// Instead, you get {}, which means Object
console.log(new Number(3)); // {}
// But, you can get the most basic value if you want:
console.log(new Number(3).valueOf()); // 3

Can we say that String is an object in Javascript?

I'm always confused when I hear strings are primitives in JS, because everybody knows that string has different methods like: length, indexOf, search etc.
let string = "Please locate where 'locate' occurs!";
let pos = str.lastIndexOf("locate");
let position = str.search("locate");
It's true that everything in JavaScript is just like object because we can call methods on it. When we use new keyword with string it becomes an object otherwise it's primitive type.
console.log(typeof new String('str')); //object
console.log(typeof 'str'); //string
Now whenever we try to access any property of the string it box the the primitive value with new String()
'str'.indexOf('s')
is equivalent to
(new String(str)).indexOf('s').
The above process is called as "Boxing". "Boxing" is wrapping an object around a primitive value.
Strings are not objects, they are native types, like numbers, but if you want to access the method on it they are boxed with String object. The same happen with numbers you can call (10).toString() but in fact you're calling toString on Number instance that wraps 10, when you call the method.
Not certainly in that way.
If you try to use a class method for a primitive, the primitive will be temporarily wrapped in an object of the corresponding class ("boxing") and the operation will be performed on this object.
For example,
1..a = 2;
It's equal to:
num = new Object(1.);
num.a = 2;
delete num;
So, after executing the operation, the wrapper will be destroyed.
However, the primitive itself will remain unchanged:
console.log( 1..a ) // undefined
Every data type is a object in JavaScript.
String, array, null, undefined . Everything is a object in JavaScript

Primitives and Objects

Definitive JavaScript by David Flanagan makes a distinction between Objects and Primitives.
He defines the primitives as Number, String, Boolean, Null, and Undefined, as does the standard.
However, would it be more accurate to define a primitive, as subset of object, i.e. to call them Primitive Objects.
Because they have their own methods and are complex entities.
Actual Question
Would Primitive Object be more accurate than Object when defining String, Boolean, and Number?
Objects and primitives are distinct:
typeof 42 === "number"
typeof new Number(42) === "object"
new Number(42) !== 42
However, when necessary, primitives are automatically wrapped by temporary objects, which can be automatically converted back into primitives:
(42).toString() === "42"
new Number(42) == 42
new Number(42) + 1 === 43
Especially in the context of the Java and C# programming languages, this sort of behavior is called autoboxing. As wrapper objects have some confusing characteristics, for example:
Boolean(new Boolean(false)) === true
it is good practice to avoid intentionally storing them in variables and instead use primitives whenever possible.
It's not about semantics, look:
var threePrimitive = 3;
var threeObject = new Number(3);
threePrimitive.toFixed(2); // 3.00
threeObject.toFixed(2); // 3.00
threePrimitive.foo = true
threeObject.foo = true;
threePrimitive.foo; // undefined
threeObject.foo; // true
Primitives are wrapped in objects when you try to call a method on them, but after initial use the object is thrown away.
As for how this is stated in the specification, I'm not 100% sure, but here is what I think (based on the tips left by Bergi in one of his answers. Section 11.2.1 states that the accessor properties should be evaluated as follows:
Let baseReference be the result of evaluating MemberExpression.
Let baseValue be GetValue(baseReference).
(...)
Then in 8.7.1 we see the following:
The following [[Get]] internal method is used by GetValue when V is a
property reference with a primitive base value. It is called using
base as its this value and with property P as its argument. The
following steps are taken:
Let O be ToObject(base).
Let desc be the result of calling the
[[GetProperty]] internal method of O with property name P.
If desc is
undefined, return undefined.
If IsDataDescriptor(desc) is true, return
desc.[[Value]].
Otherwise, IsAccessorDescriptor(desc) must be true so,
let getter be desc.[[Get]]. If getter is undefined, return undefined.
Return the result calling the [[Call]] internal method of getter
providing base as the this value and providing no arguments.
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. The only situation where such an actual
property access that uses this internal method can have visible effect
is when it invokes an accessor function.
Would Primitive Object be more accurate then Object when defining
String, Boolean, and Number?
Please note that I'm not saying that numbers are not objects here, I'm pointing out that it appears ambiguous. This is the kind of thing that confuses JavaScript newcomers.
The distinction is mostly academic, but there is one case where it seems ambiguous: literals represent primitive objects except when the literal appears to represent a number. You can't apply a method directly to a literal integer* symbol:
1.toString();
SyntaxError: identifier starts immediately after numeric literal
…but you can apply methods of Numbers:
Number(1).toString();
'1'
…and a name that contains a number is a Number:
x = 4;
x.toString();
'4'
I think this is actually a parsing problem, but I don't really know why the parser can't tell that 1 is a Number as easily as it can tell that "abc" is a String. I suppose it has to do with the semantic ambiguity of the . symbol. (Is it a decimal point or a method operator?)
*JavaScript doesn't actually have integers. I just mean a symbol that consists entirely of [0-9]+.

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.

What is the difference between "new Number(...)" and "Number(...)" in 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.

Categories

Resources