JavaScript Advanced (triple) value passing and reference passing

Source: Internet
Author: User

From the beginning of C language sometimes to tell some details or the bottom of things, I like to use C language, because C more convenient to describe the memory of things. To give an example, the swap function, I believe that some programming experience people have seen, the statement is as follows, the function body I will not write, you brain to fill.
    1. void Swap1 (int A, int b);
    2. void Swap2 (int* A, int* b)

Here Swap1 is unable to exchange two number of values, SWAP2 can. Then why? The textbook will say, the first is the value of the pass, the second is a reference pass, passing is a pointer, so the second can. Well, that's the same explanation, and I'll explain what happens when we call these two functions, why one can be exchanged and the other can't. For the sake of description, I write out the calling code for the two functions.
  1. int main () {
  2. int a = 3;
  3. int b = 4;
  4. Swap1 (A, b);  //At this time a = 3, b = 4;
  5. int* pa = &a;
  6. int* PB = &b;  //For convenience of explanation, add these two temporary variables, otherwise directly write Swap2 (&a, &b) words, this line of code do too much, not good explanation.
  7. SWAP2 (PA, Pb);  //At this time a = 4, b = 3;
  8. return 0;
  9. }

The execution of the function is in the stack, describing the situation in the stack when the Swap1 execution begins and ends. The diagram on the left is before execution and the right picture is after execution. When the main function calls the SWAP1 function, the two into the parameter, a, a, a stack, the compression stack is copied, when the Swap1 execution, modified the SWAP1 stack space of two values, but the main function of the two values are not affected. This is the value pass. The value of the input parameter is copied to the stack to pass in the parameters. Let's look at the picture of SWAP2 in the left-hand side of the image before execution. Where the leftmost column is the memory address. Here the address, the stack direction, the address sequence are examples. As you can see, the so-called reference pass, in fact, is the value of the pass, the transfer of time or the use of copy pressure stack, just pass the "value" is an address. Swap2 execution, *a = temp. Assign a value to *a, which means to modify the value of the memory that the address points to, because the address points to the location in the stack space of the main method, so the original value is modified. The above is the C language in the implementation of the SWAP function memory of the details, let us discuss the JS in the call function. Because JS does not have the & this address symbol, then JS in the end of the transfer is what? Back to JS JS data types have numbers, booleans, arrays, strings, objects, null, undefined. So when you use these data types as arguments to a function, is it either a reference pass or a value pass? First, the conclusion: Boolean, a number is a value passed, a string, an array, and an object is a reference pass. In fact, strings, arrays can also act as objects. null and undefined at the time of passing, I don't know. If you have a familiar God, please help to explain. Here, the younger brother first thanks. Boolean, when the number is passed as a parameter, its implementation is the same as the C language, here do not repeat. The local variable of the caller is also copied to the stack and passed to the callee. Let me describe in detail how the object is passed. As an example of a function, suppose you need to implement a function to reverse an incoming array, reverse, there are two implementations below, please see what the problem is:
  1. function Reverse1 (array) {
  2. var temp = [];
  3. For (var i = array.length-1; i >-1; i--) {
  4. Temp.push (Array[i]);
  5. }
  6. Array = temp;
  7. }
  8. function Reverse2 (array) {
  9. var temp = [];
  10. For (var i = array.length-1; i >-1; i--) {
  11. Temp.push (Array[i]);
  12. }
  13. For (var i = 0; i < Array.Length; i++) {
  14. Array[i] = Temp[i]
  15. }
  16. }

Both of these functions are the first to store an inverted array in temp, and then assign a value to the parameter array, that is, to assign the value differently. This different assignment method also leads to the difference of the result, the result is that REVERSE1 cannot complete the work, REVERSE2 can. To answer this question, let me tell you about JS, how the objects in memory are stored. When a line of code var temp = [] is run, this is the case in memory:

Where the blue is the stack, the black box is the heap, used to dynamically allocate memory, the most right green represents the start address of this heap. That is, when declaring an object, the content stored in the stack is just a pointer to the real content in the heap. Based on this, let's look at how memory is implemented when the function Reverse1 executes. For the convenience of example, suppose that the incoming array is [+/-];

For execution before, after execution. When the function Reverse1 executes, in is passed in as a parameter. When passing in a parameter, a reference like C is passed, a copy of the address is copied, and the stack is uploaded to the child function. So the variables in the two function are pointing to the same position. When Reverse1 executes, the inverse of the array is stored in temp, and when the last row is assigned, you see a graph of the following faces, and the array in REVERSE1 does point to the new inverse ordinal group, but the local variable in the caller does not move. Therefore, the REVERSE1 cannot complete the reverse order function.

Then we'll see Reverse2. The second loop in the Reverse2 copies the contents of the array one by one, in fact the memory space it manipulates is the area that the array points to, and we know that the array and in are pointing to the same area, so the in point area is also changed.

To summarize what has been said above,

    1. JS in Boolean, the number is the basic data type, is the value of the pass. Cannot be passed as a reference. So the swap function of the basic data type cannot be implemented in JS.
    2. The object is a reference pass. When passing an object to a child function, the address is passed. The child function uses this address to manipulate the incoming object. However, if the child function modifies the location that the address points to, the change cannot be used for the caller.
    3. A reference pass is actually a value pass, except that the value passed in is an address, and that the address points to a memory that holds the object's data. This is similar to the reference passing in C.
In particular, stringstring is a built-in object for JS, so according to the above, it is a reference pass. So I'm going to ask you to write a function that modifies the incoming string and adds quotation marks to both ends. So obviously, the following function is wrong.
    1. function foo (s) {
    2. s = "\" "+ S + " \ ""
    3. }
So what is the correct function to write? You might think that you should use the function of a string object to modify the contents of a string. It's right to think so, but unfortunately, the string provided by JS does not have any function to modify the contents of the string. Some say no, such as String join function, concat, touppercase,tolowercase function. In fact, these two functions simply return a new string object whose original value has not been changed. You can do the experiment to see this. So after the string object is set up, it can no longer be changed, so it is not possible to modify its value with a child function. And because string can use = = to determine whether its content is equal, its various aspects are similar to the basic data type. But a little bit different, consider the following example:
  1. var a = 1
  2. var B = 1
  3. A = = B //true
  4. A = = B //true
  5. var S1 = "SDF"
  6. var s2 = "SDF"
  7. S1 = = S2 //true
  8. S1 = = = S2 //true
  9. S3 = New String ("SDF")
  10. S1 = = = S3 //false

For numbers, it is estimated that you have no doubt. So for a string, = = compares the contents of two strings, this should not be questioned. what about = = =? And why is S1===S2 for true,s1===s3 false? When comparing strings with = = =, in fact the address of two objects is compared. The address of the string S1 the value "SDF", and S3 is the address of a new object. They are not equal, this is very well understood. So how do S1 and S2 explain it? This is because the JS engine has a static string store, when declaring a string constant, it will go to the store to find whether there is no identical string, if any, return the string, no longer in the static string area reinitialization of a string object. This explains why S1 = = = S2. By the way, it is the immutability of the string, and the constant string area of the two features, Java and JS are the same. However, the std::string of STL in C + + is mutable.

Note: In this article, the JS Execution Memory sample graph is not the real JS engine execution time physical memory look like. The implementation of physical memory depends on the JS engine.

JavaScript Advanced (triple) value passing and reference passing

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.