This article has been updated to the front-end technology public number: want to raise a cat front, welcome partners to pay attention to 😀

Recently on Github saw a very interesting question about JS continuous assignment, feel a lot of details, so take out to share

var a = { n:1 };

var b = a;

a.x = a = { n:2 };

console.log(a.x);	// undefined
console.log(b);		// { n:1, x:{n:2} }
Copy the code

First of all, when exploring this question, I think we need to have the following knowledge reserves:

  • JavaScript data types and pointer directivity
  • Assignment operators and order of operations

JavaScript data type and pointer pointing

JavaScript data types are divided into two types: basic data types where values are stored in stack memory and reference data types where values are stored in heap memory

Unlike other languages, JavaScript does not allow direct manipulation of memory (in this case, when an object is assigned to a value, in fact, when an object is assigned to a property). Instead, it allows manipulation of objects by reference.

That is, when we assign a value of a reference type to a variable (such as an object), we assign a reference to the object (i.e. its address in memory).

Assignment operators and order of operations

The JavaScript assignment operator = has the lowest precedence after, and is combined from right to left

Such as:

var a = b = 1;
Copy the code

In fact, it can be seen as:

var a = (b = 1);
Copy the code

In JavaScript, the order of operations is left to right.

What do you mean? So let’s look at this problem with this little bit of knowledge

Process analysis

The first line:

var a = { n:1 };
Copy the code

This step is easy to understand, declare a variable a, and give the variable given an object, and the variables in the stack memory value is the object of reference, this reference points to the heap memory of a certain value, the value of {n: 1}, in order to facilitate the understanding of the follow-up, I will be the value of heap memory space is called n

The second line:

var b = a;
Copy the code

This line is easy to understand. Create a variable B and assign it to object A. In stack memory, a and B are different, they’re two variables, but their Pointers are the same, pointing to the same heap, our N, because they hold the same value in stack memory, at the same address

The third line:

a.x = a = { n:2 };
Copy the code

This line is the heart of the whole subject. This line can be seen as:

a.x = (a = { n:2 });
Copy the code

Remember when we said that the order of operations in JavaScript is left to right?

Here our a.x first performs the operation, which creates a new attribute x in the heap referred to by a and gives the initial value undefined, i.e. an extra attribute x in N

After creation, the reference on the left already refers to x in N and will be suspended until a = {N :2} on the right is assigned.

Let’s look at the assignment on the right. Note that after the assignment on the right, our A no longer points to N, but to {N :2}.

Because of our variablebThey put theNThe address that led to ourNNot becauseaChange the reference and be destroyed.

Ok, now that the assignment on the right is complete, we also assign the final result to the x property in N, which gives us the reference to the object {N :2}

In fact, the above line of code can be seen as:

b.x = undefined;
a = { n:2 };
b.x = a;
Copy the code

Now let’s print a and B again. The result is actually equivalent to:

a = {
	n:2
}

b = {
	n:1.x: {
		n:2}}Copy the code

Because a direct reference to a nonexistent member of an object is automatically created and given an initial value of undefined, printing a.x gives undefined

I think this problem is still quite a pit, there is a lot of room for variation. For example, var b = a; This point, because of this, is not going to cause a to change the reference and destroy the original heap memory space, so you can try to work on this again and make a similar change.