The question of passing values by value or by reference in JavaScript is discussed.
Recently I encountered an interesting question: "Is the value in JS passed by value or by reference ?"
Before analyzing this problem, we need to know what is call by value and call by reference ). In computer science, this part is called Evaluation Strategy ). It determines how values are transmitted between variables and between real parameters during function calls.
Pass by value VS. Pass by reference
Call by value is the most common evaluation policy: the function parameters are copies of the passed real parameters when called. Modifying the parameter value does not affect the real parameter.
When a call by reference is passed, the function parameters receive implicit references of real parameters instead of copies. This means that if the value of the function parameter is modified, the real parameter is also modified. Both point to the same value.
Passing by reference will make it more difficult to trace function calls and sometimes cause some subtle bugs.
Because duplicate cloning is required each time for value-based transmission, the performance is low for some complex types. Both methods have their own problems.
Let's take a look at the example of C to understand the difference between passing by value and reference:
Copy codeThe Code is as follows:
Void Modify (int p, int * q)
{
P = 27; // pass by value-p is a copy of real parameter a, and only p is modified
* Q = 27; // q is a reference of B. Both q and B are modified.
}
Int main ()
{
Int a = 1;
Int B = 1;
Modify (a, & B); // a is passed by value, B is passed 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 parameter p does not affect real parameter a, and p is only a copy of parameter.
B => q is passed by reference. Modifying the value of the parameter q also affects the value of the real parameter B.
Exploring How JavaScript values are transmitted
The basic type of JS is passed by value.
Copy codeThe Code is as follows:
Var a = 1;
Function foo (x ){
X = 2;
}
Foo ();
Console. log (a); // still 1, not affected by the value of x = 2
Let's look at the object:
Copy codeThe Code is as follows:
Var obj = {x: 1 };
Function foo (o ){
O. x = 3;
}
Foo (obj );
Console. log (obj. x); // 3, modified!
O and obj are the same object, and o is not a copy of obj. Therefore, it is not passed by value. But does this indicate that JS objects are passed by reference? Let's look at the following example:
Copy codeThe Code is as follows:
Var obj = {x: 1 };
Function foo (o ){
O = 100;
}
Foo (obj );
Console. log (obj. x); // It is still 1, and obj is not modified to 100.
If it is passed by reference, modifying the o value of the form parameter should affect the real parameter. However, the o value modified here does not affect obj. Therefore, objects in JS are not passed by reference. So how exactly does the object Value Pass in JS?
Transfer call by sharing
To be precise, the basic type in JS is passed by value, and the object type is passed by share (call by sharing, also called by object and by object sharing ). It was first proposed by Barbara Liskov In the GLU language in 1974. This evaluation policy is used in Python, Java, Ruby, JS, and other languages.
This policy focuses on: When a function is called to transmit parameters, the function accepts copies referenced by the object's real parameters (neither a copy of the object passed by value nor an implicit reference passed by reference ). It differs from passing by reference in that the assignment of function parameters in the shared transfer does not affect the value of the real parameter. In the following example, you cannot modify the obj value by modifying the o value.
Copy codeThe Code is as follows:
Var obj = {x: 1 };
Function foo (o ){
O = 100;
}
Foo (obj );
Console. log (obj. x); // It is still 1, and obj is not modified to 100.
However, although the reference is a copy, the referenced objects are the same. They share the same object, so modifying the attribute value of the object will also affect the attribute value of the real parameter.
Copy codeThe Code is as follows:
Var obj = {x: 1 };
Function foo (o ){
O. x = 3;
}
Foo (obj );
Console. log (obj. x); // 3, modified!
Because the object type is mutable, modifying the object itself will affect the reference and reference copies of the shared object. For basic types, since they are all immutable, transfer by share is no different from transfer by value, therefore, the basic JS types are both pass by value and pass by share.
Copy codeThe Code is as follows:
Var a = 1; // 1 is of the number type. It cannot be changed to var B = a; B = 6;
According to the shared transfer evaluation policy, a and B are two different references (B is the reference copy of a), but reference the same value. Because the basic type Number 1 here is immutable, there is no difference between passing by value and passing by share.
Immutable Properties
The basic type is immutable, and only the object is mutable ). for example, if the numeric value is 100, the Boolean value is true or false, modifying these values (for example, changing 1 to 3 and true to 100) makes no sense. It is easy to misunderstand that it is a string in JS. Sometimes we try to "change" the content of the string, but in JS, any seemingly "modify" Operation on the string value actually creates a new string value.
Copy codeThe Code is as follows:
Var str = "abc ";
Str [0]; // ""
Str [0] = "d ";
Str; // still "abc"; the value assignment is invalid. There is no way to modify the string content
The object is different, and the object is variable.
Copy codeThe Code is as follows:
Var obj = {x: 1 };
Object. x = 100;
Var o = obj;
O. x = 1;
Obj. x; // 1, modified
O = true;
Obj. x; // 1, not changed due to o = true
The variable obj is defined here, the value is object, and the value of the obj. x attribute is set to 100. Then define another variable o, and the value is still the object. In this case, the values of the obj and o variables point to the same object (share the reference of the same object ). Therefore, modifying the object content affects both obj and o. However, the object is not passed by reference. The o value is modified using o = true without affecting obj.