Summary of JavaScript functions

point to this

In JavaScript, this represents the context object in which the current function is executed. The value of this is determined dynamically when the function is executed and depends on how the function is called. Here are the different situations this may represent:

1. Default binding

When the function is called independently, the value of this points to the global object (window object in browsers, global object in Node.js).

function foo() {
    
    
  console.log(this);
}
foo(); // window(浏览器中)或 global(Node.js 中)

2. Implicit binding

When a function is called as a method of an object, the value of this points to the object.

var obj = {
    
    
  name: "张三",
  sayName: function() {
    
    
    console.log(this.name);
  }
};
obj.sayName(); // 张三

3. Show binding

Change the execution context of the function through the call, apply or bind method, thereby explicitly binding this to the specified object.

function sayName() {
    
    
  console.log(this.name);
}
var obj1 = {
    
     name: "张三" };
var obj2 = {
    
     name: "李四" };
sayName.call(obj1); // 张三
sayName.apply(obj2); // 李四
var sayName2 = sayName.bind(obj1);
sayName2(); // 张三

4. new binding

When the constructor is called using the new operator, the value of this points to the newly created instance object.

function Person(name) {
    
    
  this.name = name;
}
var p = new Person("张三");
console.log(p.name); // 张三

It should be noted that if an arrow function is used, the value of this is determined when it is defined and will not be changed dynamically. So when using this in an arrow function, its value is usually the context in which it was defined.

Closure

In JavaScript, a closure means that a function can access and manipulate variables in its outer scope, and these variables can retain their values ​​and states even after the function execution ends. Closures are a very common and important concept in JavaScript.

Closures are implemented by defining another function inside a function and returning it as a return value, thus forming a closure. The returned function can access variables in the scope in which it was defined, and these variables will not be destroyed after the function ends because they are referenced by the closure.

Here is an example of using a closure to implement a counter:

function createCounter() {
    
    
  var count = 0;
  return function() {
    
    
    count++;
    console.log(count);
  };
}
var counter1 = createCounter();
counter1(); // 输出 1
counter1(); // 输出 2
counter1(); // 输出 3
var counter2 = createCounter();
counter2(); // 输出 1
counter2(); // 输出 2

In the above code, the createCounter function returns an internally defined anonymous function that references the variable count in the outer scope. Each call to the createCounter function creates a new closure, so counter1 and counter2 are two independent counters.

Closures also have some special applications, such as using closures to implement function currying, delayed calculation, modularization, etc. It should be noted that since closures will keep the variables in the function in memory, excessive use of closures may cause memory leaks, so you need to pay attention to the reasonable use of closures.

execution context

In JavaScript, execution context (Execution Context) refers to the environment when JavaScript code is executed. It contains all the information required to execute the code, such as variables, functions, scope, this, etc. On each function call, a new execution context is created.

There are three types of execution context:

  1. Global Execution Context : An execution context created when JavaScript code starts executing. It is the outermost execution context in the code and the default execution context for the entire program. There is only one global execution context, and it exists throughout the life cycle of the program.

  2. Function Execution Context : The execution context created every time a function is called. It contains information such as variables, functions, and scope chains defined within the function.

  3. eval Execution Context : The execution context created when using the eval function. It contains the variables, functions, scope chain and other information required by the executed code fragment.

An execution context goes through the following two stages when it is created:

  1. Creation phase: When the execution context is created, the JavaScript engine will create variable object (Variable Object), scope chain (Scope Chain), this pointer and other information.
  2. Execution phase: After the execution context is created, the JavaScript engine will execute the code in it and update information such as variable objects and scope chains.

During the creation phase, the execution context completes some operations in the following order:

  1. Create a variable object (Variable Object): A variable object is an object that stores information such as variables and function declarations. It is created when the execution context is created.
  2. Create a scope chain (Scope Chain): A scope chain is a linked list structure that stores the current execution context and all outer execution context variable objects. When the JavaScript engine looks for a variable in the current context, it will first look in the current variable object. If it cannot find it, it will look up the scope chain.
  3. Determine this pointer: This pointer is a pointer to the current object when the function is executed. It is determined when the function is called.

During the execution phase, the execution context completes some operations in the following order:

  1. Execute code: The JavaScript engine executes the statements in the code in the order it is written.
  2. Update variable object: The variables in the variable object will be updated to the latest values ​​during execution.
  3. Execution function declarations: If function declarations exist in the code, they will be added to the variable object during the creation phase, and these functions can be called directly during the execution phase.

Execution context and scope are very important concepts in JavaScript, and understanding how they work is very important for writing high-quality JavaScript code.

Prototype/Prototype Chain

In JavaScript, every object has an internal link to its prototype, which is the prototype object of the object created through the constructor. prototypeThe prototype object of the constructor can be accessed through the property.

When we create an object, the JavaScript engine will first check whether the object itself has a certain property or method. If not, it will search in the prototype object of the object. If it is still not found, it will continue to search in the prototype object. Search the prototype object until the property or method is found, or the end of the prototype chain is reached.

Prototype objects can implement inheritance of properties and methods. When we access a property or method of an object, if the object itself does not have that property or method, the JavaScript engine will look up the prototype chain until it finds the property or method.

Here are some common concepts of prototype chains:

**1. Prototype:** Each object has a prototype object, which is used to implement the inheritance of properties and methods.

**2. Prototype Chain: **Since the prototype object of each object is also an object, the prototype object also has its own prototype object. They form a chain structure called a prototype chain.

  1. Constructor: A function used to create objects. Objects created through the constructor have a prototype object, which is prototypeset through the properties of the constructor.

  2. __proto__Properties: Each object has a __proto__property that points to the prototype object of the object, through which properties and methods on the prototype chain can be accessed. However, in actual development, it is not recommended to use __proto__properties. Instead, use Object.getPrototypeOfthe method to obtain the prototype object of the object.

Here is a simple example that demonstrates how to use prototypes to implement property and method inheritance:

// 定义一个构造函数
function Person(name, age) {
    
    
  this.name = name;
  this.age = age;
}

// 在 Person 构造函数的原型对象上定义一个方法
Person.prototype.sayHello = function() {
    
    
  console.log(`Hello, my name is ${
      
      this.name} and I am ${
      
      this.age} years old.`);
};

// 创建一个 Person 对象
const person1 = new Person('Alice', 25);

// 调用 Person 对象的 sayHello 方法
person1.sayHello(); // 输出:Hello, my name is Alice and I am 25 years old.

// 创建一个 Student 对象,继承自 Person 对象
function Student(name, age, grade) {
    
    
  Person.call(this, name, age); // 调用父类构造函数,初始化父类的属性
  this.grade = grade;
}

// 通过原型继承,使 Student 对象也拥有 sayHello 方法
Student.prototype = Object.create(Person.prototype);
Student.prototype.constructor = Student;

// 创建一个 Student 对象
const student1 = new Student('Bob', 18, 10);

// 调用 Student 对象的 sayHello 方法

Scope and scope chain

In JavaScript, scope refers to the accessible scope of a variable (including a function), that is, the code area where the variable can be accessed. In JavaScript, there are two types of scope: global scope and function scope.

Global scope refers to variables defined at the outermost level of code that can be accessed throughout the program. Function scope refers to the variables defined inside the function, which can only be accessed inside the function.

The scope chain in JavaScript is composed of a series of nested function scopes, which forms a layer-by-layer nested scope chain. When the code accesses a variable in a certain scope, the JavaScript engine will first search for the variable in the current scope. If it is found, it will use the variable directly. If it is not found, it will continue to search in the outer scope until it finds the variable. Or search until the global scope.

The generation process of the scope chain is determined when the function is defined, and it is determined by the scope environment when the function is defined. When a function is executed, a new execution environment is created whose scope chain contains the scope environment when the function was defined. If other functions are defined inside the function, the scope chain of the new function will also include the scope environment of the outer function, thus forming a nested scope chain.

The concepts of scope and scope chain are relatively basic and important concepts in JavaScript. They are very helpful for understanding variables, functions, closures, etc. in JavaScript. Here is a simple example that demonstrates the use of scope chains:

// 全局作用域
const globalVar = 'globalVar';

function outer() {
    
    
  // 外层函数作用域
  const outerVar = 'outerVar';

  function inner() {
    
    
    // 内层函数作用域
    const innerVar = 'innerVar';

    console.log(innerVar); // 输出 'innerVar'
    console.log(outerVar); // 输出 'outerVar'
    console.log(globalVar); // 输出 'globalVar'
  }

  inner();
}

outer();

In the above example, the global scope contains a global variable globalVar, the outer function scope contains a variable outerVar, and the inner function scope contains a variable innerVar. When a function is executed inner, it first looks for variables in its own scope innerVar, then looks for variables in the outer scope outerVarand global scope globalVar, and finally outputs the values ​​of these variables. Due to the scope chain mechanism, the inner function can access the variables of the outer function, but the outer function cannot access the variables of the inner function. This is the concept of closure, that is, a function can access variables in the scope in which it was defined, even if the scope in which the function was defined has been destroyed.

Here is an example of using closures:

function outer() {
    
    
  const outerVar = 'outerVar';

  function inner() {
    
    
    console.log(outerVar);
  }

  return inner;
}

const innerFn = outer();
innerFn(); // 输出 'outerVar'

In the above example, outerthe function returns an inner function innerand the variable inneris accessed within the function outerVar. When a function is called outer, it creates a new execution environment and pushes outerthe functions in the current scope chain into the scope chain as scope environments. When the function is executed outer, its scope environment will be destroyed, but because innerthe function refers to outerVarthe variable, the value of this variable is not released, so innerthis variable can be accessed in the function.

Guess you like

Origin blog.csdn.net/qq_48439911/article/details/130270348