简体   繁体   中英

How variable assignment and strict equality work in Javascript, in a little more depth

We all know JS has objects and a group of primitives .

Let's examine the following assignments.

a = 'foo';
b = a;
c = 'foo'
a === b; //true
a = b = c = undefined;

The way I visualize the variable assignment process in JS for years now is like this.

  • a = 'foo';

A new primitive string foo is created and added in a memory location. The variable a now points to that location in memory.

  • b = a

The variable b points to the same location in memory as a , meaning it points to foo .

  • c = 'foo'

The primitive string foo already exists in memory, so the variable c just points to that

  • a === b; //true

The variables a and b are compared by reference, meaning the only thing that is checked is whether they point to the same location in memory and not if their values are the same. This means that no matter how long the strings, this should be a quick operation.

  • a = b = c = undefined

The variables a , b , c all point to the primitive undefined . The primitive foo is not pointed at by any variables so it's garbage collected.

All the above should also apply to object properties.

I was 101% sure that this is how JS works, until today when I had a talk with a co-worker who was equally sure as me that when two variables are compared, even with a strict equality ( === ), they are compared by value and not by reference .

Hence, if we have to compare two variables that were both assigned a very very large string, eg

a = 'a huge string';
b = 'a huge string';
a === b; //true, takes 1ms

This equality check would take longer than if the two variables were just assigned a one letter string. eg

a = 'a small string';
b = 'a small string';
a === b; //true, takes 0.1ms

In conclusion

Is any of my bullet points (my understanding) incorrect? Does strict equality compares values instead of reference?

Technical answers are welcomed and encouraged.

Thanks.

Whe you work with primitive types (Number, String, Boolean) you are comparing their values.

"string one" == "string one";  // true
3 == 3;  // true
false == false;  // true

Even undefined works similar:

undefined == undefined;  // true

The exception is NaN:

NaN == NaN;  // false

When you compare objects, you compare their references. For example:

var obj1 = { "name": "Charles" };
var obj2 = { "name": "Charles" };
obj1 == obj2;  // false
obj1 === obj2;  // false

Based on the ECMAScript spec, === compares values, not references, unless those values are objects.

For string comparison, they are compared lexicographically, as in checking if all chars are equal in the same order.

If x and y are exactly the same sequence of code units (same length and same code units at corresponding indices), return true; otherwise, return false.

Here's the general algorithm for a === b :

// if both are undefined, return true
// if both are null, return true
// if both are numbers
//    if a is NaN, return false
//    if b is NaN, return false
//    if are equal numeric values, return true
//    if a is +0 and b is -0, return true
//    if b is +0 and a is -0, return true
//    return false
// if both are strings
//    if all chars equal and in the same order, return true
//    return false
// if both are booleans
//    if both are true or both are false, return true
//    return false
// if both are objects
//    if are equal references, return true
//    return false
// return false

I wrote a small tool a while ago that demonstrates the == and === algorithm (as per the ES5 spec) that might help.

Now, as far as reusing memory from already defined strings, such as your example of a = 'foo' and c = 'foo' pointing to the same memory for efficiency reasons, that is an optimization that an engine can do to make things faster but is not part of the spec.

In fact, this is called String Interning , and many languages do it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM