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

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

Related

Understanding the typeof operator in Javascript

I came across the following table which states the internal [[Class]] property of an object and its corresponding value that the typeof operator returns.
Value Class Type
-------------------------------------
"foo" String string
new String("foo") String object
1.2 Number number
new Number(1.2) Number object
true Boolean boolean
new Boolean(true) Boolean object
new Date() Date object
new Error() Error object
[1,2,3] Array object
new Array(1, 2, 3) Array object
new Function("") Function function
/abc/g RegExp object (function in Nitro/V8)
new RegExp("meow") RegExp object (function in Nitro/V8)
{} Object object
new Object() Object object
One thing to note here is the typeof correctly returns the primitive data types associated in Javascript.
However, it returns an object type for an array which inherits from the Array.prototype, but returns a function type for a function that is inheriting from the Function.prototype.
Given everything is an object in Javascript (including arrays, functions & primitive data type objects), I find this behaviour of the typeof operator very inconsistent.
Can someone throw some light on how the typeof operator works in reality?
This is slightly odd, idiosyncratic Javascript behaviour. It's inherited from the earliest days of Javascript and probably would not be written in such a way today.
Nonetheless, we are where we are with Javascript, so we have to deal with it!
The thing is that values in Javascript are either objects or they are primitives. This is a design decision. They cannot be anything else. The types of primitives are:
strings
numbers
booleans
symbols (from ES2015)
the special value undefined
the special value null (for which typeof also returns object)
Anything and everything else is an object. This is by design. Arrays are objects, so typeof returns object, as does every other object that is not callable (i.e. a function). See the spec for typeof.
The better question is to ask why you want to test if something is an array. You probably don't need to, especially as array-like objects such as NodeLists are not arrays but are like them in many ways.
The best solution in most cases is to call Array.from on the value supplied: then you know that it is an array.
Use typeof operator in JavaScript
'Typeof' is an operator which is used to return a string description of the type of a variable.
Example
console.log(typeof 42);
output: "number"
console.log(typeof true);
output: "boolean"

Comparison Behaviour of JavaScript Objects

We suppose that we have 3 variables : a,b and c
var a = new Boolean(true);
var b = true;
var c = new Boolean(true);
console.log("First comparison : ", a == b);
// true
console.log("Second comparison : ", b == c);
// true
console.log("Contradiction : ", a == c);
// false
I already know that the keyword 'new' creates a new object.
The type of this object, is simply object.
Mathematically, how can we explain this contradiction ?
In the first two examples, since the comparison involves a primitive value of b, a and c end up being coerced to primitives. In the last case, on the other hand, you are comparing two distinct objects, and therefore no coercion takes place.
To be precise, the double-equal comparison with a boolean uses this rule from the spec (taking the case of b == c):
If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y.
So this means that ToNumber(b) is compared with c. ToNumber(b) is 1. So we are comparing 1 with c. Next, the following rule is applied:
If Type(x) is either String or Number and Type(y) is Object,
return the result of the comparison x == ToPrimitive(y).
So this means we compare 1 with ToPrimitive(c) which is ToPrimitive(Boolean(true)). ToPrimitive invokes valueOf, which yields 1. So we compare 1 to 1. QED.
In the case of your third example, the following portion of the spec applies:
If Type(x) is the same as Type(y), then...Return true if x and y refer to the same object. Otherwise, return false.
To answer your question:
Mathematically, how can we explain this contradiction ?
It's not a matter of mathematics. It's a matter of the definition of comparisons in the JS spec.
Mathematically, how can we explain this contradiction?
If you think this is a contradiction is probably because you assumed that == defines an equivalence relation.
But it doesn't:
It doesn't satisfy reflexivity, e.g. NaN != NaN.
It doesn't satisfy transitivity, as you noticed.
It satisfies symmetry, though, but that alone is not enough.
I don't think this kind of behaviour can be explained from a mathematical standpoint.
What you are doing on the variables a and c is commonly referred as "boxing": taking a Javascript primitive value (undefined, null, String, Number, Boolean, Symbol in ES6) and calling it with the newoperator.
The result of:
var a = new Boolean(true);
is a Javascript Objectwrapping a Boolean primitive value.
The same invocation pattern implicitly happens when you use a primitive value as the context (this) in some of the language built-in facilities such as Function.prototype.call and Function.prototype.apply
Even replacing ==with === would yield the same results, and that's because of how the Objects comparison work in JS.

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

Why is "" == [null] true in JavaScript?

I know JavaScript has lots of insane results with comparisons between types, though I don't fully understand why. Came across this one today.
Why does
"" == [null]
evaluate to true in JavaScript?
Some more Javascript equality amusement, thanks to #Qantas:
Why does 2 == [2] in JavaScript?
Why is 0 == "" true in JavaScript
Why if([]) is validated while [] == false in javascript?
Why does !{}[true] evaluate to true in JavaScript?
The "Abstract Equality Comparison Algorithm" has many parts, but the important one here is this:
If Type(x) is either String or Number and Type(y) is Object,
return the result of the comparison x == ToPrimitive(y).
(There's a mirror-image of that too.) So, because "" is a string and [null] is an object, we've got to first convert [null] to a string by calling ToPrimitive([null]). That's an internal operation described as follows, when it's asked to convert an Object instance to a primitive value:
Return a default value for the Object. The default value of an object is retrieved by calling the [[DefaultValue]] internal method of the object, passing the optional hint PreferredType. The behaviour of the [[DefaultValue]] internal method is defined by this specification for all native ECMAScript objects in 8.12.8.
Now, the [[DefaultValue]] internal operation will call .toString() on the object and return that value. Try [null].toString() in your browser console:
> [null].toString()
""
And there you have it.
Edit: And why is [null].toString() an empty string? Because the .toString() operation on Array instances always just calls .join(), and that always yields an empty string for null and undefined values. Thus an array of one null ends up as just a single empty string.
It's according to the arcane type-conversion rules of Javascript. Rule #8:
If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y).
So the comparison is between x = "" and y = [null] converted to a string using ToPrimitive. Converting an array with one null element results in an empty string (because Array.toString() returns a comma-separated list of values), hence they evaluate to equal.
Why does "" == [null] evaluate to true?
Because you're comparing an array with a string, using the non-strict equality operator == - so it will try to cast values to the same type before comparing them.
What happens in detail is:
you compare a string to an object, so the object is cast to a string:
When an array is cast to a primitive value, it's .toString() method is invoked (as explained in detail by the other answers), which is equivalent to calling .join():
which in case of a one-element array that only contains an undefined or null value returns the empty string
which finally is equivalent to the empty string
This third step is the unexpected one ([null]+"" != null+""), if it actually did cast that to a string the result would have been "null" and your equality be false.
Let's look at the spec and follow through each step
Going via the Abstract Equality Comparison Algorithm (§11.9.3):
typeof ""; // string and typeof [null]; // object so not applicable
neither is null or undefined so not applicable
same as 2
neither is a number, not applicable
same as 4
neither is a bool, not applicable
again not applicable
finally, something applicable, now we need to know ToPrimitive([null])
§9.1 ToPrimitive for Objects says we need to work out [[DefaultValue]] (§8.12.8), points 1 and 2 of which say if you can do .toString and it gives a string, return that, so
[null].toString(); // ""
So we are now performing the comparison "" == "" which is true by the Abstract Equality Comparison Algorithm's point 1. d.
If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false.
JavaScript is weakly typed; you can use the following to get a false result:
"" === [null]
The value null is a JavaScript literal representing null or an "empty" value, i.e. no object value is present. It is one of JavaScript's primitive values.
The value null is a literal (not a property of the global object like undefined can be). In APIs, null is often retrieved in place where an object can be expected but no object is relevant. When checking for null or undefined beware of the differences between equality (==) and identity (===) operators (type-conversion is performed with the former).
typeof null // object (bug in ECMAScript, should be null)
typeof undefined // undefined
null === undefined // false
null == undefined // true

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]+.

Categories

Resources