0

I have written a prototype method that I would like to extend the Array object with:

Array.prototype.indicesOf = function(val) {
 var res = [];
 for (var a=0;a<this.length;a++) {
  if (this[a] === val) {
   res.push(a);
  }
 }
 return res;
}

When I go to test it, I'm expecting to get strict equality, but I'm not.

Here is that test:

var res1 = document.getElementById('result_1');
var res2 = document.getElementById('result_2');

Array.prototype.indicesOf = function(val) {
 var res = [];
 for (var a=0;a<this.length;a++) {
  if (this[a] === val) {
   res.push(a);
  }
 }
 return res;
}

var a = ["a", "c", "e", "a", "b", "d", "a", "f"];
res1.innerHTML = a.indicesOf("a").toString();

var b = [{name : "test1"}, {name : "test2"}];
res2.innerHTML = b.indicesOf({name : "test1"});
<div id="result_1"></div>
<div id="result_2"></div>

I'm not sure what I am doing wrong, and I was hoping someone could help with an answer that explains why my case for var a is working as expected, but my case for var b is not being considered equal.

Can someone help me gain some comprehension as to what is happening when comparing equality among (not between) different data types?


This has already been marked as a duplicate, which I highly disagree with, but let me explain why, and try to do this in a logical way. I'm not trying to offend anyone (it's simply not my intent), and I truly would like to know the answer.

The reasoning: The links provided to justify the marked as duplicate, themselves link to other links, which link to more links that don't really help me understand the problem of why it doesn't seem possible to compare different data types using the equality operators ===.

They tell you that it will equal false when comparing either an Object to an Object or an Array to an Array, but don't really explain why.

When I have a problem:

Let's call this one 'Problem A' 1 + 9

And

Let's call this one 'Problem B' 8 + 2

I can check to see if these two separate problems are equal, and the answer is yes, because they equate to the same answer.

When using the same basic logic looking at an Object which has the same properties however, in my mind they should equate to the sum of their parts (properties in this case) logically.

Implicating this:

var additionProblem = function(a1, a2) {
    this.addend1 = a1;
    this.addend2 = a2;
    this.answer = this.addend1 + this.addend2;
}

var problem1 = new additionProblem(1, 9);
var problem2 = new additionProblem(8, 2);

//When compared via ===
//(problem1 === problem2) returns false (understandable)
//(problem1.answer === problem2.answer) returns true (understandable)
//BUT
//(9+1 === 8+2) returns true (also understandable)
//({name : "problem1"} === {name : "problem1"}) returns false (not understandable using this logic)
//

If I can compare one PROBLEM to another that is the sum of its (different) parts and have it return true, and yet at the same time compare two objects/arrays that have even more exacting equality than the two obviously different PROBLEMS, then I would really like to know how to properly use the === &/OR == for my purposes please.

The reasons given in the so called answers and comments of the linked justifications are seriously lacking what others have settled for as answers, and do not even come close to asking what I am asking for.

The best I can glean from these answers are simply solutions to approach the underlying problem of Javascript having no built-in way of handling Object-to-Object equality comparison, NOT memory pointer comparison.

I would like to know, why by design of the language specification there is not a built-in operator to thoroughly check the contents (Key/Value pairs) of one instance of an object, and compare it to the contents of another instance of an object.

Can anyone shed light on this?

Is there any plans for this type of functionality to be incorporated into the language in the future, or will this be like Promises, where everyone builds a different implementation of it into a library, and then eventually have it become part of the language standard, once it gets hashed out in the open source community?

Rick Riggs
  • 336
  • 2
  • 12
  • 1
    The problem is that `{} === {} //false` because these are two *different* objects, even if their contents are the same. You will find that even the built-in `[{name : "test1"}, {name : "test2"}].indexOf({name : "test1"})` will fail for the same reason. – VLAZ May 14 '18 at 18:49
  • @Barmar actually the question was different and unique, only poor titled.... it is about generalizing a function for arg of different types – Attersson May 14 '18 at 18:51
  • Your function needs to treat object specially, and use one of the solutions there to test them. – Barmar May 14 '18 at 18:53
  • I will respect your judgement then – Attersson May 14 '18 at 18:55
  • @Barmar I tend to think along the same lines as Atterson, my question is not the same as the one you quoted / linked to. My underlying problem might be there, however I was looking to understand why different types where not being treated the same when comparing equality, not specifically why two objects are not being treated as equal. I had hoped that my tests of more than just object types would explain that. Could you help me re-word my question to not offend the duplication? – Rick Riggs May 14 '18 at 19:20
  • `==` for objects is pointer equality, not contents equality. `{ a: 1} == {a: 1}` is `false`. – Barmar May 14 '18 at 19:31
  • But `x = { a: 1}; x == x` is true – Barmar May 14 '18 at 19:31
  • @Barmar Im using ```===``` not ```==``` – Rick Riggs May 14 '18 at 19:32
  • @RickRiggs There's no difference between `==` and `===` if the operands are the same type. I've added another duplicate that may be more apropos. – Barmar May 14 '18 at 19:35
  • @RickRiggs when talking about two variables of the same type then `==` will work the same as `===`. This is always true `(a == b) === (a === b)` as long as `typeof a === typeof b`. Also, regarding your edit - why are you so dismissive of the other answers? With very little research it should become apparent that `var a = {}` stores the *reference* to the object. So `a == b` will be true only if `b` is **literally** pointing to the same object: `a = b`. People don't discuss this when talking about comparing objects because it's not some sort of secret and it's easy to find out. – VLAZ May 14 '18 at 21:22
  • @vlaz It is just hard for me to comprehend using the logic I laid out in my question. I look, and I see the answers, I don't dismiss them, they just don't seem to make sense to me, the "problems" in my logic cases don't base themselves on memory pointing, so in my mind I'm struggling to find the consistency. I looked on [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Equality_comparisons_and_sameness) and get a pretty comprehensive chart comparing ```==```, ```===```, & ```Object.is```. – Rick Riggs May 15 '18 at 11:13
  • The problem really is, there is NO valid comparison for what I am looking for without having to be mutilating the objects themselves, or crawling them extensively. I will eventually write my own equality comparison prototype on the Object type, and this baffles me that I even have to, as it is already a documented MISS on the language itself. So sad. Especially since the common way of describing Javascript, is everything (just about) is an Object. – Rick Riggs May 15 '18 at 11:14
  • `The problem really is, there is NO valid comparison for what I am looking for without having to be mutilating the objects themselves, or crawling them extensively.` Yes. That's exactly why all other questions focus on that. `and this baffles me that I even have to` well, you don't. I can't even think of many significant instances when I've wanted to check if an object has the same values as another one - complex ones will have a unique property (like ID) which can be compared, simple ones you can just check the one or two properties it has. There are also libraries that do the work for you. – VLAZ May 15 '18 at 11:23
  • @vlaz In my code, I am checking for instance occurrences of the same obj def. So that I can id the records, change them in the same way (appendage/manipulation of methods properties values). The main issue that still remains in my mind: I'm asking ```Why does the logical comparison breakdown this way```, & others seem to read this to mean, ```How do I determine equality```. In fairness the short answer to why is simply ```because the language has nothing built-in for equality this way```, I was hoping for a more thorough answer as to why the language by design chose not to solve this case. – Rick Riggs May 15 '18 at 12:33

1 Answers1

-2

The problem is due to the fact that the data should be out of scope, ie the function is over.

var res = [] // global scope over the function

var res1 = document.getElementById('result_1');
var res2 = document.getElementById('result_2');

var res = [];

Array.prototype.indicesOf = function(val) {
 for (var a=0;a<this.length;a++) {
  if (this[a] === val) {
   res.push(a);
  }
 }
 return res;
}

var a = ["a", "c", "e", "a", "b", "d", "a", "f"];
res1.innerHTML = a.indicesOf("a").toString();

var b = [{name : "test1"}, {name : "test2"}];
res2.innerHTML = b.indicesOf({name : "test1"});
<div id="result_1"></div>
<div id="result_2"></div>
enter code here
Erdal
  • 64
  • 9