Pass by value VS. Pass by reference
Call by value is the most commonly used evaluation strategy: the formal parameters of a function are copies of the actual parameters passed when called. Modifying the value of a formal parameter will not affect the actual parameter.
When passing by reference (call by reference), the formal parameters of the function receive an implicit reference of the actual parameter, rather than a copy. This means that if the value of the function parameter is modified, the actual parameter will also be modified. Both point to the same value.
Passing by reference makes tracking of function calls more difficult and sometimes causes some subtle bugs.
Pass by value Since replicas are cloned each time, performance is lower for some complex types. Both methods of passing values have their own problems.
Let's first look at a C example to understand the difference between passing by value and reference:
The code copy is as follows:
void Modify(int p, int * q)
{
p = 27; // Pass by value - p is a copy of the actual parameter a, only p is modified
*q = 27; // q is a reference to b, and both q and b are modified
}
int main()
{
int a = 1;
int b = 1;
Modify(a, &b); // a pass by value, b pass by reference,
// a has not changed, b has changed
return(0);
}
Here we can see:
a => When p is passed by value, modifying the value of the formal parameter p does not affect the actual parameter a, p is just a copy of a.
b => q is passed by reference. When modifying the value of the formal parameter q, it also affects the value of the actual parameter b.
Explore how JS value is passed
The basic type of JS is passed by value.
The code copy is as follows:
var a = 1;
function foo(x) {
x = 2;
}
foo(a);
console.log(a); // Still 1, not affected by the assignment of x = 2
Let’s look at the object:
The code copy is as follows:
var obj = {x : 1};
function foo(o) {
ox = 3;
}
foo(obj);
console.log(obj.x); // 3, modified!
Explain o and obj are the same object, and o is not a copy of obj. So it's not passed by value. But does this mean that JS objects are passed by reference? Let's look at the following examples:
The code copy is as follows:
var obj = {x : 1};
function foo(o) {
o = 100;
}
foo(obj);
console.log(obj.x); // Still 1, obj has not been modified to 100.
If it is passed by reference, modifying the value of the formal parameter o, it should affect the actual parameter. But modifying the value of o here does not affect obj. Therefore, objects in JS are not passed by reference. So how do the value of the object be passed in JS?
Pass call by sharing
To be precise, the basic types in JS are passed by values, and the object types are passed by sharing (call by sharing, also called by object and shared by object). It was first proposed by Barbara Liskov. in the 1974 GLU language. This evaluation strategy is used in Python, Java, Ruby, JS and other languages.
The point of this strategy is that when a function passes argument, the function accepts a copy of the object's actual argument reference (neither a copy of the object passed by value, nor an implicit reference passed by reference). The difference between it and passing by reference is that the assignment of function parameters in a shared pass will not affect the value of the actual parameter. As in the following example, the value of obj cannot be modified by modifying the value of the formal parameter o.
The code copy is as follows:
var obj = {x : 1};
function foo(o) {
o = 100;
}
foo(obj);
console.log(obj.x); // Still 1, obj has not been modified to 100.
However, although the reference is a copy, the referenced object is the same. They share the same object, so modifying the attribute value of the formal parameter object will also affect the attribute value of the actual parameter.
The code copy is as follows:
var obj = {x : 1};
function foo(o) {
ox = 3;
}
foo(obj);
console.log(obj.x); // 3, modified!
For object types, since the object is mutable, modifying the object itself will affect the sharing of the reference and reference copy of the object. For basic types, since they are both immutable, there is no difference between passing by sharing and passing by value (call by value), so JS basic types are both in line with passing by value and in line with passing by sharing.
var a = 1; // 1 is type number, immutable var b = a; b = 6;
According to the evaluation strategy passed by shared, a and b are two different references (b is a reference copy of a), but references the same value. Since the basic type number 1 here is immutable, there is no difference between passing by value and passing by share here.
Immutable properties of basic types
The basic types are immutable, and only objects are mutable. For example, numeric values 100, boolean values are true, false, and modifying these values (for example, turning 1 into 3, and turning true into 100) does not make sense. What is easier to misunderstand is string in JS. Sometimes we try to "change" the contents of the string, but in JS, any "modify" operation that seems to be a string value is actually creating a new string value.
The code copy is as follows:
var str = "abc";
str[0]; // "a"
str[0] = "d";
str; // Still "abc"; assignment is invalid. There is no way to modify the content of the string
The object is different, the object is variable.
The code copy is as follows:
var obj = {x : 1};
obj.x = 100;
var o = obj;
ox = 1;
obj.x; // 1, modified
o = true;
obj.x; // 1, will not change due to o = true
Here the variable obj is defined, the value is object, and then the value of the obj.x property is set to 100. Then define another variable o, and the value is still this object object. At this time, the values of the two variables obj and o point to the same object (sharing a reference to the same object). Therefore, modifying the content of the object has an impact on both obj and o. However, the object is not passed by reference. The value of o is modified by o = true and will not affect obj.