I know that identical objects are not equal, i.e:
var obj = { name: "Value" };
var obj2 = { name: "Value" };
console.log("obj equals obj2: " + (obj === obj2)); //evaluates to false
Yet primitive types are:
var str = "string1";
var str2 = "string1";
console.log("str equals str2: " + (str === str2)); //evaluates to true
My question is why. Why are objects and primitives treated differently? If an object is nothing but an empty container, with only the attributes you specify to put in the container, why wouldn't the container's identical attributes evaluate to be the same? I looked around for this answer on SO and elsewhere, but didn't find an answer.
Is a JS object treated as something different in the DOM than a primitive type?
Thanks
I know that identical objects are not equal, i.e:
var obj = { name: "Value" };
var obj2 = { name: "Value" };
console.log("obj equals obj2: " + (obj === obj2)); //evaluates to false
Yet primitive types are:
var str = "string1";
var str2 = "string1";
console.log("str equals str2: " + (str === str2)); //evaluates to true
My question is why. Why are objects and primitives treated differently? If an object is nothing but an empty container, with only the attributes you specify to put in the container, why wouldn't the container's identical attributes evaluate to be the same? I looked around for this answer on SO and elsewhere, but didn't find an answer.
Is a JS object treated as something different in the DOM than a primitive type?
Thanks
Share Improve this question asked Jan 31, 2014 at 19:21 user3871user3871 12.7k36 gold badges140 silver badges283 bronze badges 1- your asking about the implementation of the language so i dont know for sure, but imagine having to do internal checks of every single field of every single object that is pared, then having to define what exactly is equal. im guessing the designers decided to leave such equalities of objects up to the programmer. – celeriko Commented Jan 31, 2014 at 19:27
5 Answers
Reset to default 3This seems to really be a question about ===
so let's look at the Strict Equality Comparison Algorithm, in which point 7 says
Return
true
if x and y refer to the same object. Otherwise, returnfalse
.
So what does it mean to be "the same object"? It means they don't just look like eachother, but are at the same place in memory too. This means that the only time when an Object is ===
to an Object is when they're the same thing.
var a = {},
b = {}, // identical to `a`
c = a; // same as `a`
a === b; // false
a === c; // true
b === c; // false
When a variable's value is an object, well, it isn't an object: it's a reference to an object. Two variables that contain references to the same object are indeed equal:
var myObj = { hello: "world" };
var a = myObj;
var b = myObj;
if (a == b) alert("YES!!"); // YES!!
When the ==
operator has object references on both sides, the parison made is to test whether the objects refer to the same object. When primitive values are involved, the semantics are different: the values are directly pared.
Generally, ===
operator checks for types, and if they are the same, checks values. Object type contains a reference, so, to be equal, they have to reference the same object and be of the same type. String literal value is not a reference, it is a value, so the ===
will produce true for string literals, but not for "abc" ===
new String("abc") because latter is an Object.
More information can be found here: A lot of details can be explored from here: Which equals operator (== vs ===) should be used in JavaScript parisons?
First off, JavaScript objects aren't part of the DOM. The DOM (Document Object Model) are the HTML elements which make up your page. They cooperate together, but aren't directly linked.
Basically, yes, primitives are a special case. You can kind of think of it as if the value of a primitive is a constant (in a sense).
For example, take the example of the number 5. No matter how many times I declare 5, 5 will always equal 5. Thus, it isn't a stretch to say that {var a holding the value 5} is equivalent to {var b holding the value 5}. This concept is a little fuzzier with strings, but it still holds. A string that is "abc" is always the same as any other variable holding a string that is "abc".
This doesn't apply to objects either.
If you have two variables hold the same object, they are eqivalent.
var a = {};
var b = a;
console.log(a == b); // true
console.log(a === b); // true
However, if we create two objects that look similar:
var a = {};
var b = {};
console.log(a == b); // false
console.log(a === b); // false
This seems a bit weird at first, but think about the inner workings that are going on. Consider that when you pass an object in to a function, if you change that object, it is changed outside of the function to. It's passed by reference.
This means you can think of a pointer (a memory address) being stored in the variables. So, if you imagine that they have memory address in them (like 0x123456 and 0x654321), then it makes a little more sense (0x123456 and 0x654321 are different, so you wouldn't expend them to be equal). They are two separate things taking up their own area in the memory.
Make sense?
You can answer to this question at several levels.
strings
Factually, yes, strings are handled differently from objects as far as strict parison operator is concerned.
Semantically, that is more convenient than having to resort to strcmp
or equivalent mechanisms to pare two strings.
Implementation-wise, the cost is neglectible, so JavaScript can offer you that convenience.
By the way, people telling the strict equality operator checks if both variables point to the same memory location are wrong. In case of strings, === will succeed if the string contents are equal, wherever they might be located in memory.
Objects
Semantically, contrary to primitive types like numbers or strings, it is difficult to offer a consistent set of parison operators for objects.
You could do an in-depth parison for equality, but greater/lower operators would make little sense.
The choice of Javascript is rather inconsistent here.
- the semantics of equality parison (be it
==
or===
) are limited to references
(i.e.==
or===
will succeed if the references are equal).
Implementation-wise, a deep parison could be quite costly.
There are also subtelties as how to interpret undefined properties.
At any rate, JavaScript did not choose to implement a deep parison, so if you want one, you'll have to do it yourself.
And there have been terabytes of code written to try and provide the ideal in-depth object parison function.
- ordered parison is handled quite differently.
You can define a valueOf
method that will return whatever primitive value you want to be used for ordered parison, e.g
myObject.prototype.valueOf = function(){return this.my_parison_value; };
If not explicitely defined, valueOf
will default to "[object Object]"
.
So if you don't supply a valueOf
method:
<
and>
operators will always returnfalse
(which kind of makes sense).>=
and<=
will always returntrue
, regardless of the references being equal or not
(which makes a lot less sense).
Now if you take the pain to define a valueOf
, equality parison will still not use it.
The only way to have a consistent behaviour would be to bine <=
and >=
, e.g.
if (a >= b && a <= b) { // equality using valueOf
For browser-supplied primitive objects like DOM elements, the behaviour of ordering operators depends on what the browser decided to return as a default value.
I would not reend using that unless you really know what you're doing.
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745306790a4621757.html
评论列表(0条)