0

var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var img = new Image();
img.crossOrigin = 'anonymous';
img.src = 'https://upload.wikimedia.org/wikipedia/commons/thumb/6/6a/JavaScript-logo.png/64px-JavaScript-logo.png';

var obj = {
    id: 1,
    color: [240, 219, 79]
};
console.log(obj.color); // (3) [240, 219, 79]

img.onload = function() {
    ctx.drawImage(img, 0, 0);
    var data = ctx.getImageData(0, 0, canvas.width, canvas.height).data;

    var pixelColor = [data[0], data[1], data[2]];
    console.log(pixelColor); // (3) [240, 219, 79]
    console.log(pixelColor == obj.color); // false

    var objectId = getObjectId(pixelColor);
    console.log(objectId); // undefined
}

function getObjectId(color) {
    if (obj.color == color)
    {
        return obj.id;
    }
  return;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title></title>
</head>
<body>
    <canvas id="canvas" width="64" height="64"></canvas>
</body>
</html>

I'm trying to use the pixelColor array assembled from ImageData as an argument for a getObjectId() function that will return the id of an object with the specified color array. Why is the function returning undefined? And why is the if condition in it unfulfilled?

Edit: added the getter function.

  • Does this answer your question? [How to determine equality for two JavaScript objects?](https://stackoverflow.com/questions/201183/how-to-determine-equality-for-two-javascript-objects) – jsejcksn Mar 13 '22 at 17:12
  • Does this answer your question? [How to check if two arrays are equal with JavaScript?](https://stackoverflow.com/questions/3115982/how-to-check-if-two-arrays-are-equal-with-javascript) – KetZoomer Mar 13 '22 at 17:13
  • No, those don't answer my question. I'm trying to use the `pixelColor` array assembled from ImageData as an argument for a function that will return the `id` of an object with the specified `color` array. I assume that it's returning `undefined` because the two arrays are not equal. – Stevo Ilišković Mar 13 '22 at 17:18
  • Your question as stated is a duplicate of the ones linked above. In Javascript, objects are not equal just because all their contents are equal, and arrays are a kind of object. It also seems like this is a [XY problem](https://xyproblem.info/) due to your comment, so if you could edit the question or post another one with the actual problem you're trying to solve, maybe we can be of more help to you. – This company is turning evil. Mar 13 '22 at 17:31
  • 1
    @Kroltan Okay, I rephrased the question and added the getter function. Is that good enough – Stevo Ilišković Mar 13 '22 at 17:38
  • You should add an `else` condition in `getObjectId` function, in case the `if` does not match. I suspect the `if` condition is not being fulfilled. – Jagrut Sharma Mar 13 '22 at 17:46
  • 1
    @JagrutSharma Yes, that was my original question - `Why those two arrays don't match`. – Stevo Ilišković Mar 13 '22 at 17:50

1 Answers1

1

Your getObjectId is comparing the argument passed to obj.color, which is an array.

In JavaScript, arrays are objects, and objects have an identity. Equality operators like == or === check for this identity, not for all the contents of the objects to be the same. (== also does some funky implicit type conversions, which is why it's good practice to prefer === unless you actually need the funny behaviour)

Identity is what allows objects to be modified without changing other objects like it, nor having to become a new, different object:

var a = [1, 2, 3];
var b = [1, 2, 3];
var c = b;
b.push(4);

console.log(a, b); // prints [1, 2, 3] [1, 2, 3, 4]
console.log(c == b, c); // prints true [1, 2, 3, 4]

What you are looking for is called structural equality, and JavaScript does not offer a built-in way to do it. There are a bunch of libraries and StackOverflow answers that provide a function to do it, but in your case, if you assume the input is an array too, you can use Array#every, comparing each component of the array to the corresponding one in the input:

if (obj.color.every((x, i) => x == color[i])) {
    return obj.id;
}