-1

I am looking at the spec:

http://www.ecma-international.org/ecma-262/5.1/#sec-11.9.6

http://www.ecma-international.org/ecma-262/5.1/#sec-9.12

I have seen JS code do this:

var a = function(){}
var b = function(){}
var c = a;

console.log(a === b);
console.log(a === c);

the code works as expected, it seems to use strict equality - it doesn't convert the functions to strings and then compare strings - that would be crazy - it uses memory address or something like with Java, right?

How does it actually work? Does anyone know? The spec doesn't seem to mention function comparison, or objects for that matter.

Alexander Mills
  • 90,741
  • 139
  • 482
  • 817
  • `a` and `c` are the same exact object. JS has share-by-value semantics. – elclanrs Apr 11 '18 at 01:09
  • note that I first saw function identity comparison in the Node.js event emitter library, so it's in common use – Alexander Mills Apr 11 '18 at 01:09
  • @elclanrs yes and JS knows if something refers to the same exact object or not, but how – Alexander Mills Apr 11 '18 at 01:10
  • Let me put it a different way, as an end user of JS, I cannot grab the memory address of an object like you can do in other languages. To compare for strict equality in Java, for example, we compare memory location. – Alexander Mills Apr 11 '18 at 01:11
  • The basic premise of your post is incorrect. When comparing objects, `==` vs. `===` is irrelevant. You are comparing an object ***reference*** against an object ***reference***. No coercion to strings would occur. – Scott Marcus Apr 11 '18 at 01:11
  • I don't care whether it's == or ===. how does JS work behind the scenes in either case when comparing objects? – Alexander Mills Apr 11 '18 at 01:11
  • Object variables don't store the actual object. They store a reference to the memory location where the object is stored. Object A and Object B will only ever be equal if they are actually just one single object that two variables both point at. – Scott Marcus Apr 11 '18 at 01:12
  • yes that is correct, and how does the JS engine know the memory location, and how come I cannot discover that myself? – Alexander Mills Apr 11 '18 at 01:13
  • "*How does it actually work?*" is irrelevant. ECMA-262 explicitly omits implementation details, leaving it entirely up to the developers. Memory address is one possibility of many. "*The spec doesn't seem to mention function comparison, or objects for that matter*" note that functions are objects, and objects are explicitly mentioned in both the [abstract](http://ecma-international.org/ecma-262/8.0/#sec-abstract-equality-comparison) (`==`) and [strict](http://ecma-international.org/ecma-262/8.0/#sec-strict-equality-comparison) (`===`) equality comparison algorithms. – RobG Apr 11 '18 at 01:23
  • @RobG maybe I can't read good, but ain't see no object comparison algo, can you link to it? – Alexander Mills Apr 11 '18 at 01:24
  • @AlexanderMills—in abstract, step 1 covers both being objects, step 9 covers comparing objects to all other types. In strict, step 3 covers objects using [*SameValueNonNumber*](http://ecma-international.org/ecma-262/8.0/#sec-samevaluenonnumber), where objects are covered in step 8: "*If x and y are the same Object value…*". – RobG Apr 11 '18 at 01:30
  • 1
    @AlexanderMills—oh, my references are to the current spec, [*ECMAScript 2017*](http://ecma-international.org/ecma-262/8.0/), whereas you've referenced ECMA-262 ed 5.1. I don't have a link to EMCAScript 2018, I guess it will be made available when it's released, maybe in June? The latest draft is [*ECMAScript 2019*](https://tc39.github.io/ecma262/). – RobG Apr 11 '18 at 01:43

1 Answers1

1

it uses memory address or something like with Java, right?

Pretty much. A variable referencing an object is essentially a reference to a memory location - objects (and functions) are only equal if they reference the same location in memory. Thus, { foo: 'bar' } !== { foo: 'bar' } because each object was created separately.

All non-objects (primitives) can be considered to compare by value, though.

CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • but how does it get the memory location? if the engine can get it, I should be able to get it at runtime too – Alexander Mills Apr 11 '18 at 01:12
  • 1
    It's all under the hood - other than for when comparing such as with `===`, there's no way to figure out the memory address of any particular function or object - it's too low-level for the Javascript visible to the programmer. – CertainPerformance Apr 11 '18 at 01:13
  • yeah that's a shame, it's strange to me that C/C++ can know the memory location, but we cannot get it in JS land. oh well. – Alexander Mills Apr 11 '18 at 01:14
  • it's also strange that it's not in the spec, but maybe it is in the spec and I just haven't dug that deep – Alexander Mills Apr 11 '18 at 01:15
  • @AlexanderMills It's not strange because the spec. leaves the implementation details up to the user-agent. You don't need to know the memory address, you have the variable. – Scott Marcus Apr 11 '18 at 01:16
  • @AlexanderMills C/C++ are compiled languages with a much higher overhead than JavaScript. In general, scripting languages have to be more lightweight and therefore, it's unrealistic to expect them to be comparable. – Scott Marcus Apr 11 '18 at 01:17
  • 2
    There's no need to get memory addresses in NodeJS because memory is automatically managed for you. There are ways to still use the same functionality with buffers for high-performance applications. In general, if you really *need* memory management then you probably don't want JavaScript. [There are ways in V8/Node to use C++ code if needed](https://nodejs.org/api/addons.html#addons_c_addons). Lack of memory management in JS also partially a remnant of JavaScript being born in the browser where you don't want it to have memory access for security reasons. – Alex W Apr 11 '18 at 01:22
  • As Alex W says, there's no imperative to use memory address. An implementation may keep it's own index of values and when two identifiers hold the same value, then they are `===`. If the value is a reference, then `===` means they are the same reference, likely an index key. Whether it's to memory or some other storage is up to the implementors. – RobG Apr 11 '18 at 01:36