Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does Javascript's indexOf() resolve references

I was confusing myself a little with a thought experiment and now I'm looking for some advice. Its about ECMAscript references and the Array.prototype.indexOf() method.

Lets start easy:

var container = [ ];
// more code
container.push( 5 );
container.push( 7 );
container.push( 10 );

So now we pushed some "primitive values" into our ECMAscript array (whether or not that statement is true I'll come back for), at least I imagined it like this so far. A call to

container.indexOf( 7 );

will return 1 as expected. The big question I'm having is, if .indexOf() really compares the primitive value or if in reality a Number() object is created + stored and its reference is getting compared. This becomes a little more obvious if we re-write that like so:

var a = 5,
    b = 7,
    c = 10;

var container = [ ];

container.push( a );
container.push( b );
container.push( c );

container.indexOf( b );

Until this point, one could still easily argue that all .indexOf() needs to do is to compare values, but now lets look at something like this:

var a = { name: 'a', value: 5 },
    b = { name: 'b', value: 10 },
    c = { name: 'c', value: 15 };

var container = [ ];
// more code
container.push( a );
container.push( b );
container.push( c );

Here, we filled that container array with object-references and still, .indexOf() works as expected

container.indexOf( b ) // === 1

while a call like this

container.indexOf({ name: 'b', value: 10 });

obviously returns -1 since we are creating a new object and get a new reference. So here it must internally compare references with each other, right?

Can some ECMAscript spec genius confirm that or even better link me some material about that ?

A side question on this would be if there is any possibly way to access an internally stored object-reference within a lexicalEnvironment respectively Activation Object.

like image 232
jAndy Avatar asked Sep 27 '12 10:09

jAndy


People also ask

What does the indexOf () function do?

The indexOf() method returns the position of the first occurrence of specified character(s) in a string. Tip: Use the lastIndexOf method to return the position of the last occurrence of specified character(s) in a string.

What is the use of indexOf () in array?

The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.

What is the use of indexOf () method of string object in JavaScript?

The indexOf() method, given one argument: a substring to search for, searches the entire calling string, and returns the index of the first occurrence of the specified substring.

What happens if indexOf does not exist?

What happens if indexOf does not exist? Java String indexOf() method returns the position of the specified string or char from the given string. If the target string or character does not exist, it will return -1.


2 Answers

It boils down to indexOf() comparing against each array property in turn using the same algorithm as the === operator.

The relevant section of the ECMAScript 5 spec is section 15.4.4.14, step 9, section b (highlighting mine):

If kPresent is true, then

i. Let elementK be the result of calling the [[Get]] internal method of O with the argument ToString(k).

ii. Let same be the result of applying the Strict Equality Comparison Algorithm to searchElement and elementK.

iii. If same is true, return k.

References:

  • indexOf()
  • Strict Equality Comparison Algorithm
like image 66
Tim Down Avatar answered Sep 23 '22 10:09

Tim Down


I'm not sure if this is guaranteed across all ECMAScript implementations or not, but the Mozilla documentation states that it uses strict equality to make the comparison (===). As such this would exhibit the behaviour you describe, comparing by values on primitives, but by reference on objects (see strict equality).

like image 37
Thor84no Avatar answered Sep 19 '22 10:09

Thor84no