Chapter 4 variables, scopes, and Memory Problems

Values of base and reference types

  • Basic type: access by value, can manipulate the actual value stored in a variable, occupies a fixed amount of memory, and is therefore stored in stack memory. (Undefined, Null, Boolean, Number, String)
  • Reference type: Access by reference, cannot directly manipulate the memory space of the object. When you manipulate an object, you’re actually manipulating a reference to the object, which is stored in heap memory. (Object)
1. Copy variable values
  • Basic type: Creates a new value on a variable object and copies the value to the location allocated for the new variable. Thereafter, the two variables can participate in any operation without affecting each other.

  • Reference type: Also copies the value stored in the variable object into the space allocated for the new variable. The difference is that this value is actually a pointer to an object stored in the heap. After the copy operation is complete, both variables will actually refer to the same object. Thus, changing one variable affects the other.

2. Pass parameters
  • When you pass a value of the primitive type to a parameter, the passed value is copied to a local variable.
  • When you pass a value of a reference type to a parameter, the value’s in-memory address is copied to a local variable, so changes to the local variable are reflected outside the function.
3. Detection type

Instanceof: an object used to check what type the reference type is. The instanceof operator returns true if the variable is an instanceof the given reference type (identified by its stereotype chain).

alert(person instanceof Object); // Is the person variable Object?
alert(colors instanceof Array); // Is the variable colors Array?
alert(pattern instanceof RegExp); // Is the variable pattern RegExp?
Copy the code

The Typeof operator can be used to determine what base type a value is, and the instanceof operator can be used to determine what reference type a value is.

Execution environment and scope

1. Execution environment

Execution environment: Defines variables or other data that functions have access to. Each execution environment has a variable object associated with it. All variables and functions defined in the environment are stored in this object.

  • The global execution environment is the outermost execution environment and varies according to the host environment. In Web browsers, the global execution environment is considered a Window object.

  • After all code in an execution environment is executed, the environment is destroyed, along with all variables and function definitions stored in it (the global execution environment is not destroyed until the application exits, such as closing a web page or browser).

  • Each function has its own execution environment. When the execution stream enters a function, the function’s environment is pushed onto an environment stack. After the function is executed, the stack pops up its environment, returning control to the previous execution environment.

2. Scope

Scope chain: Ensures orderly access to all variables and functions that the execution environment has access to. The front end of the scope chain is always the variable object in the environment of the currently executing code; The next variable object in the scope chain comes from the containing (external) environment, and the next variable object comes from the next containing environment. This continues to the global execution environment; The variable object of the global execution environment is always the last object in the scope chain.

Identifier resolution: The process of searching for identifiers level by level along the scope chain.

If a variable is initialized without a VAR declaration, it is automatically added to the global environment.

Garbage collection

JavaScript has automatic garbage collection, and the execution environment is responsible for managing the memory used during code execution.

How it works: Find variables that are no longer used and free up memory. The garbage collector does this periodically at fixed intervals (or at predetermined collection times during code execution).

Local variables exist only during the execution of a function. In this process, local variables are allocated in stack (or heap) memory, which can be freed when the function completes.

1. Mark clearing (common)
  • The garbage collector runs by marking all variables stored in memory; When a variable enters the environment, it is marked as “entering the environment”; When a variable leaves the environment, it is marked as “out of the environment”;
  • Next, it strips the tags of variables in the environment and those referenced by variables in the environment;
  • The marked variable is then considered to be ready for deletion;
  • Finally, the garbage collector completes the memory cleanup.
2. Reference counting

It keeps track of how many times each value is referenced. When a variable is declared and a reference type value is assigned to the variable, the number of references to the value is 1. If the same value is assigned to another variable, the number of references to the value is increased by one. Conversely, if a variable containing a reference to that value takes another value, the number of references to that value is reduced by one.

When the number of references to this value goes to zero, the memory space it occupies can be reclaimed. This way, the next time the garbage collector runs, it frees the memory occupied by values with zero references.

Problem: circular reference (object A contains A pointer to object B, and object B contains A reference to object A)

function problem(){
    var objectA = new Object(a);var objectB = new Object(a); objectA.someOtherObject = objectB; objectB.anotherObject = objectA; }Copy the code

To avoid the problem of circular references, it is best to manually break them when they are not in use and eliminate circular references;

objectA.someOtherObject = null
objectB.anotherObject = null
Copy the code