English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

A Brief Discussion on References and Copies in JavaScript (Value and Address)

It seems that few people talk about references and copies in JavaScript, but understanding this concept can help understand a lot of things

Let's talk about some very basic things first, and see what each data type passes in JavaScript

Reference: objects, arrays, functions

Copy: numbers, booleans

Strings are explained separately because of their particularity, it is impossible to determine whether it is passing by reference or by value (because the value of a string cannot be changed, so worrying about this issue is also meaningless) but it is obviously a value comparison when used for comparison (more on that later)

Let's talk about the specific embodiment in use

The most common use is assignment

var a = 1;
var b = a;  //It assigns a copy of the value of a
b ++;
alert(a);  //"1"The modification of b does not affect a
/****************************************/
var a = [1}
var b = a;   //It assigns a reference to a 
b[0] ++;
alert(a); //"2"The modification of b also affects a, but of course b = [2This modification is useless for a.

Function parameters

Passing by value: A copy of the value is passed to the function, and modifications to it are not visible externally

var a = 1;
var b = 2;
function change(a,b) {
 var c = a;
 a = b;   //New reference overlay
 b = c;
 alert(a);  //"2"     
 alert(b);  //"1"
};
change(a,b);
alert(a);  //"1"     
alert(b);  //"2"

Passing by value:Passing by reference: The reference to a value is passed to the function, and modifications to it are visible externally in the function, but new references overlaying it are not visible externally, for example

var a = [1, 2, 3}
var b = [5, 6}
function change(a,b) {
 a[0] = 4;  //Modifications to its properties are visible externally 
 var c = a;
 a = b;   //New reference overlay
 b = c;
 alert(a);  //"5,6"     
 alert(b);  //"4,2,3"
};
change(a,b);
alert(a);  //"4,2,3"
alert(b);   //"5,6"

From the result, it can be seen that a and b have not been swapped because the new reference is overlaid on the external invisible part. This is very natural because the function only gets the reference and does not have the power to change the reference.

This is different below

var a = [1, 2, 3}
var b = [5, 6}
function change() {
 var c = a;
 a[0] = 4;
 a = b;
 b = c;
};
change();
alert(a);  //"5,6"
alert(b);  //"4,2,3"

Here, the swap is successfully implemented 

Again, we have to mention JavaScript's block scope. This would definitely result in an undefined error in some languages because JavaScript does not have block scope. So when it can't find variables a, b in change, it will automatically look up to the upper level. Therefore, a, b here are references to global variables.

And the above a, b are variables in the change function. When calling the function, the references of a, b are passed and assigned to these variables. However, it cannot change the global a, b. Changing the name might make it easier to understand.

This is a little mentioned... Some have strayed from the topic...

Returning to reference and copying, here are some things to note in comparison operations

The comparison of value passing compares the values, while the comparison of reference compares the references. Different references are not equal even if the values are the same.

1 == 1;  //true
1 === 1;  //true
[0] == [0]; //false
[0][0] == [0][0];  //true
[0][0] === [0][0];  //true
[0].toString() == [0].toString();  //true 

In closures...

Closures are probably the most纠结 thing in JavaScript. It's a classic question in our department's interviews, always popular and never out of date...

Here, I won't talk about closures at all, but only about the parts involving value passing and reference. When I figure out how to clearly explain that thing with clear logic, concise language, and vivid examples, I will then go into detail about this guy that JavaScript cannot omit...

In closures, the inner function uses the local variables of the outer function by reference rather than by copying.

In fact, this is also an important part of understanding closures. It can be used to explain a very classic closure phenomenon, an example that is often used to illustrate closures.

/*Construct a function, set event handlers for the nodes in the array, and alert the index of the node when a node is clicked.*/
var add_handlers = function (nodes) {
  var i;
  for (i = 0, l = nodes.length; i < l; i ++) {
    nodes[i].onclick = function (e) {
      alert(i);  // Of course, the result here must be that alert always shows the total number of nodes...
    };
  };
};

Why does alert always show the total number of nodes instead of the expected index? This is quite easy to explain with the concepts of copying and referencing

Because the internal function uses the reference method to use the external variable instead of copying, that is to say, when I set the onclick event for each node, I pass the reference of i to alert. When I click the node to trigger the onclick event, the value of i has become the total number of nodes...

var add_handlers = function (nodes) {
  var i;
  for (i = 0, l = nodes.length; i < l; i ++) {
    nodes[i].onclick = function (i) {
      return function(){
      alert(i);  
      };
 }(i);
  };
};

The reason why the modification is correct is that at this time, a copy of the value of i is passed in, which is actually the same as a normal function. Don't be confused because of the addition of closure, return to the original thinking and you will understand, the original is the transmission of address that was mentioned above

By the way, don't be scared by the peculiar name 'closure', in fact, it is the same as the principle of the function we use in daily life. Put aside those so-called characteristics of 'longer lifetime' and 'protection of private variables' of closure, and treat it as an ordinary function (you can also view the global function as a special closure from another perspective), it is easy to understand

The key is to put aside all the ostentation and return to the most essential... And I have gone off on a tangent again...

This brief discussion on references and copies (pass by value and pass by reference) in JavaScript is all that the editor has shared with everyone. I hope it can be a reference for everyone, and I also hope that everyone will support the Yana tutorial more.

You May Also Like