Nine ES5 features to consolidate your JavaScript foundation

1. Variable declaration and scope:

Use the var keyword to declare variables

In ES5, you can use varthe keyword to declare variables. varThe following is an example of declaring a variable using the keyword:

var x = 10; // 声明一个名为 x 的变量,并赋值为 10
console.log(x); // 输出 10

function myFunction() {
    
    
  var y = 20; // 声明一个名为 y 的变量,并赋值为 20
  console.log(y); // 输出 20
}

myFunction(); // 调用函数,输出 20
console.log(y); // 报错,y 在函数外部不可见

In the above example, two variables and varare declared in different scopes by using keyword . Variables declared inside a function are only valid in the function scope, while variables declared in the global scope can be accessed throughout the code.xyyx

It should be noted that varvariables declared using the keyword will have variable hoisting (hoisting) characteristics, that is, the declaration in the scope where they are located is hoisted to the top of the scope. Therefore, a variable can be used before it is declared, but its value will be undefined.

For example:

console.log(a); // 输出 undefined
var a = 10;

In the above example, athe variable declaration is hoisted to the top of the scope, so console.log(a)no error is reported, but the output is undefined.

Function scope and global scope

Function scope and global scope are two different scope types in JavaScript.

Function scope:

  • Function scope means that variables declared inside a function are valid inside the function.
  • Variables in function scope are freely accessible within the function, but are not visible outside the function.
  • In function scope, variables can have the same name and have no influence on each other.

Example:

function myFunction() {
    
    
  var x = 10; // x在函数作用域内
  console.log(x); // 输出 10
}

myFunction();
console.log(x); // 报错,x在函数外部不可见

Global scope:

  • Global scope means that variables declared outside a function are valid throughout the code.
  • Globally scoped variables can be accessed from anywhere in the code, both inside and outside functions.
  • In the global scope, variables can be accessed by all functions and code blocks.

Example:

var y = 20; // y在全局作用域内

function myFunction() {
    
    
  console.log(y); // 输出 20,函数可以访问全局作用域中的变量
}

myFunction();
console.log(y); // 输出 20,全局作用域中的变量可以在代码的任何位置访问

It should be noted that if a variable is not declared using the or keyword inside a function var, letthe constvariable will become a global variable. Even if it is declared inside the function, it will pollute the global namespace. Therefore, try to use the or varkeyword declaration inside the function. variables to avoid accidental global variable definitions.letconst

variable promotion

Variable hoisting is a feature in JavaScript that allows variables to be accessed before they are declared.
When JavaScript code is executed, 变量的声明会被提前至其所在作用域的顶部,这就是变量提升.

Specifically, variable promotion is divided into two phases: declaration phase and initialization phase.

  1. Declaration phase:

    • Within a scope, variables and functions declared using varthe keyword, letkeyword, or functionare declared at the top of the scope in which they appear.
    • The declaration of variables is advanced, but the initialization (assignment) of variables is not advanced.
  2. Initialization phase:

    • When the code runs, the variables are initialized in the order in the code. If the variable is used before it is declared, its value will be undefined.
    • Function declarations are prepended as a whole, so the function can be called before it is declared.

Example 1 (variable declaration in advance):

console.log(x); // 输出 undefined
var x = 10;
console.log(x); // 输出 10

Example 2 (function declaration in advance):

myFunction(); // 调用函数,输出 "Hello"
function myFunction() {
    
    
  console.log("Hello");
}

Note that although function declarations are hoisted, function expressions (by assigning functions to variables) are not hoisted.

Example 3 (function expression will not be promoted):

myFunction(); // 报错,myFunction is not a function
var myFunction = function() {
    
    
  console.log("Hello");
};

In order to avoid possible problems caused by variable promotion, it is recommended to declare variables before using them and develop good coding habits.

2. Data type:

Basic data types: Number, String, Boolean, null, undefined

Reference data types: Object, Array, Function, Date

3. Function:

Function definition and calling

In programming, a function is a reusable block of code that performs a specific task or calculation. Through the definition and calling of functions, we can divide the code into small pieces, making the program structure clearer and easier to maintain and expand.

The definition of a function includes the following parts:

  1. Function name : Give the function a recognizable name for subsequent function calls.
  2. Parameter list : Defines the parameters that the function needs to receive, which can be zero or more parameters. Each parameter has a name and type.
  3. Function body : The function body is the actual execution part of the function, which contains a series of statements and algorithms used to complete specific tasks.
  4. Return value : A function can optionally return a value as a result. The type of the return value can be any type or empty.

Calling a function refers to using the function name and parameter list to execute the code in the function body . When a program needs to execute a function, it can be called by adding parentheses and a parameter list after the function name. For example, suppose we have a addfunction called that accepts two integer arguments and can add(2, 3)calculate the sum of two integers by calling .

The function call will temporarily interrupt the current execution flow and go to the function body to execute the corresponding code. Once the function completes execution, the result (if any) is returned and execution continues with the next statement in the function call.

The definition and calling of functions are important concepts in modular programming, which can improve the readability, maintainability and reusability of the code. In most programming languages, functions are one of the basic programming constructs.

Function parameters and parameter passing

In ES5, function parameters and argument passing can be done in the following ways:

  1. Named Parameters : When defining a function, you can specify some named parameters for the function, which can be used within the function body. When calling a function, you can pass parameter values ​​based on their names. For example:
function greet(name) {
    
    
  console.log("Hello, " + name + "!");
}

// 调用函数时传递参数值
greet("Alice"); // 输出:Hello, Alice!
  1. Default Parameters : In ES5, you can specify default values ​​for function parameters. If the function is called without passing a value for this parameter, the default value will be used. For example:
function greet(name, message) {
    
    
  name = name || "Anonymous"; // 设置默认值为 "Anonymous"
  message = message || "Hello"; // 设置默认值为 "Hello"

  console.log(message + ", " + name + "!");
}

greet(); // 输出:Hello, Anonymous!
greet("Alice"); // 输出:Hello, Alice!
greet("Bob", "Hi"); // 输出:Hi, Bob!
  1. Parameter passing method : In ES5, parameters are passed by value. To put it simply, the parameter value is assigned to the parameter when the function is defined. If the passed parameter is a basic type (such as string, number, etc.), then changes to the parameter value inside the function will not affect the value outside the function. If the parameter passed is an object, modifications to the parameter inside the function will affect the object passed outside the function.
function updateName(obj) {
    
    
  obj.name = "Bob"; // 修改传递的对象的属性值
}

var person = {
    
     name: "Alice" };
updateName(person);
console.log(person.name); // 输出:Bob

Note that ES5 does not provide a specific way to declare the types of function parameters. Therefore, when the parameter type needs to be checked or converted inside the function, it needs to be handled manually.

Functions as values ​​and callback functions

In ES5, functions are treated as a special kind of value that can be assigned to a variable, passed as an argument to a function, or returned from a function like any other value. This capability allows functions to be used as callbacks, functions that are called after an event occurs.

Callback functions are very commonly used in asynchronous programming . When you need to perform some action after an event completes, you can pass a callback function as a parameter to the function that triggered the event. For example, when processing AJAX requests, you can pass the success callback function and the failure callback function as parameters to the XMLHttpRequestrelevant methods of the object.

Here is a simple example showing how to use callback functions:

function fetchData(url, onSuccess, onError) {
    
    
  var xhr = new XMLHttpRequest();
  xhr.open("GET", url, true);
  xhr.onreadystatechange = function() {
    
    
    if (xhr.readyState === 4) {
    
    
      if (xhr.status === 200) {
    
    
        onSuccess(xhr.responseText);
      } else {
    
    
        onError(xhr.status);
      }
    }
  };
  xhr.send();
}

function onSuccess(response) {
    
    
  console.log("成功获取数据:", response);
}

function onError(status) {
    
    
  console.log("获取数据失败,状态码:", status);
}

fetchData("https://api.example.com/data", onSuccess, onError);

In this example, fetchDatathe function accepts a URL parameter and two callback function onSuccessparameters onError. fetchDataThe function will send an AJAX request and call the corresponding callback function based on the result of the request.

This example is just one way to apply the callback function. You can decide when and how to use the callback function according to your specific needs.

Closures and scope chains

A closure is a function that has access to variables in its own scope as well as outer scopes. In ES5, closures are a powerful and common design pattern that can be used to create private variables, modularize code, and encapsulate data.

Scope chain refers to the order in which variables are looked up when a function is created . 当函数中访问一个变量时,JavaScript引擎会首先搜索作用域链中的当前函数的作用域, if not found, continue searching the scope of the external function until the variable is found or the global scope is reached.

Here is an example of closures and scope chains:

function outerFunction() {
    
    
  var outerVariable = "外部变量";

  function innerFunction() {
    
    
    var innerVariable = "内部变量";
    console.log(outerVariable + "和" + innerVariable + "可在内部函数访问");
  }

  return innerFunction;
}

var inner = outerFunction();
inner();  // 输出:外部变量和内部变量可在内部函数访问

In this example, innerFunctionthe inner function can access outerVariablethe variables of the outer function. When outerFunctionthe function is executed, it returns innerFunctionthe function, forming a closure. This way, the inner function can access the variable within its own scope as well as within the scope of the outer function.

An important property of a closure is that it allows a variable to survive a function execution and retain its value . In the above example, even outerFunctionafter execution has completed, the variable innerFunctioncan still be accessed through the closure outerVariable.

By understanding the concepts of closures and scope chains, you can better design and organize your code, create private variables, modularize code, and avoid global namespace pollution.

4. Objects and prototypes:

Object creation and attribute access

In ES5, we can create objects in two ways: object literal syntax and constructor . Object literal syntax is a concise way to create objects directly. Constructors allow us to create objects using custom constructors.

  1. Object literal syntax:
var person = {
    
    
  name: "John",
  age: 30,
  sayHello: function() {
    
    
    console.log("Hello, I'm " + this.name);
  }
};

console.log(person.name);  // 输出:"John"
person.sayHello();  // 输出:"Hello, I'm John"

In object literal syntax, we use curly braces {}to define objects, and then define properties and methods in the form of key-value pairs. Attributes can person.namebe accessed through the object name followed by a dot (for example).

  1. Constructor:
function Person(name, age) {
    
    
  this.name = name;
  this.age = age;
  this.sayHello = function() {
    
    
    console.log("Hello, I'm " + this.name);
  };
}

var person = new Person("John", 30);
console.log(person.name);  // 输出:"John"
person.sayHello();  // 输出:"Hello, I'm John"

In this example, we define a Personconstructor named and newcall the constructor through the keyword to create the object. Inside the constructor, use thisthe keyword to refer to the newly created object, and use assignment statements to define the properties and methods of the object.

Whether it is object literal syntax or constructor, we can use dot notation to access the properties and methods of the object.

In ES5, we can also use Object.definePropertymethods to define the characteristics of a property, such as setting a property to read-only or setting the getter and setter functions of a property.

These are common ways of object creation and property access in ES5, and they can help us create and manipulate objects more conveniently.

Constructor and new operator

A constructor is a special function used to create and initialize objects. In JavaScript, newan object can be instantiated using constructors and operators.

Constructor names usually start with a capital letter to distinguish them from ordinary functions. The purpose of the constructor is to create an object and set its initial state. The constructor can contain properties and methods that become properties and methods of the instance object.

Using newthe operator to call the constructor will perform the following steps:

  1. Create an empty object.
  2. Point the prototype of this empty object to the constructor's prototypeproperties to inherit the constructor's properties and methods.
  3. Execute the constructor in the context of the new object, that is, thisbind the constructor's to the new object.
  4. If the constructor returns an object, that object is returned; otherwise, the newly created object is returned.

Here is an example of creating an object using constructors and newoperators:

function Person(name, age) {
    
    
  this.name = name;
  this.age = age;
  this.sayHello = function() {
    
    
    console.log("Hello, I'm " + this.name);
  };
}

var person = new Person("John", 30);
console.log(person.name);  // 输出:"John"
person.sayHello();  // 输出:"Hello, I'm John"

In this example, Personit's a constructor that newcreates an personobject via the operator. The constructor uses thisthe keyword internally to refer to the newly created object and to set the object's properties and methods.

Using constructors and newoperators you can easily create multiple similar objects while achieving code reusability and maintainability.

Prototypes and prototype chains

In JavaScript, every object has a special property called a prototype ( prototype), which points to another object. This object is called the prototype object ( prototype object). Prototype objects have properties and methods that can be inherited by object instances.

prototype chain

The prototype chain is the link between an object and its prototype object. If an object cannot find a property or method on itself, it will search up the prototype chain until it finds the corresponding property or method, or reaches the end of the prototype chain. Top - Object.prototype(i.e. null).

var person = {
    
    
  name: "John",
  sayHello: function() {
    
    
    console.log("Hello, I'm " + this.name);
  }
};

var john = Object.create(person);
john.age = 30;

console.log(john.name);  // 输出:"John"
john.sayHello();  // 输出:"Hello, I'm John"

In this example, we create an personobject as johnthe prototype of the object. Therefore, johnobjects inherit personthe properties and methods of objects. When an object cannot find a property or method johnon itself , it looks up the prototype chain and eventually finds those properties and methods on the object.namesayHelloperson

prototype

Every JavaScript object has a prototype object. We can prototypeget the prototype object by accessing the object's properties. prototypeA prototype object is the value of the property of the function that created the object . For example:

function Person(name) {
    
    
  this.name = name;
}

var john = new Person("John");

console.log(Person.prototype);  // 输出:{ constructor: f Person(name) }
console.log(john.prototype);    // 输出:undefined

In this example, the constructor Personhas a prototype object, which is stored in Person.prototype. When we newcreate an object using the operator Person, the prototype of that object becomes Person.prototype.

The prototype object of an object can also Object.getPrototypeOf()be obtained through the method.

console.log(Object.getPrototypeOf(john) === Person.prototype);  // 输出:true

prototypal inheritance

Through prototypes, we can achieve inheritance between objects. An object can inherit properties and methods from another object.

function Animal(name) {
    
    
  this.name = name;
}

Animal.prototype.sayHello = function() {
    
    
  console.log("Hello, I'm " + this.name);
};

function Dog(name) {
    
    
  Animal.call(this, name);   // 调用 Animal 构造函数,继承属性
}

Dog.prototype = Object.create(Animal.prototype);  // 继承原型方法
Dog.prototype.constructor = Dog;  // 修复原型链的 constructor

var dog = new Dog("Max");
dog.sayHello();  // 输出:"Hello, I'm Max"

In this example, we define two constructors: Animaland . Constructors inherit properties by calling the constructor . Then, we use the method to set the object's prototype to the object's prototype, thus inheriting the object's methods. Finally, we fixed the prototype chain's property to point to the constructor.DogDogAnimalnameObject.create()DogAnimalAnimalconstructorDog

Through prototypal inheritance, we can effectively achieve sharing and code reuse between objects, and form a flexible inheritance structure.

Inheritance implementation

  • prototype chain inheritance
  • Constructor inheritance
  • compositional inheritance
  • prototypal inheritance
  • parasitic inheritance
  • Mixed inheritance
Inheritance method describe
prototype chain inheritance prototypeImplement inheritance by setting the object's property chain
Constructor inheritance This is achieved by calling the parent class constructor inside the constructor and using callthe or applymethod
compositional inheritance Combines prototype chain inheritance and constructor inheritance
prototypal inheritance Implement inheritance by cloning an object as the prototype for a new object
parasitic inheritance Add operations to extend new objects based on prototypal inheritance
Mixed inheritance Combines multiple inheritance methods to achieve the best results

Each of these inheritance methods has its own advantages and disadvantages. Which inheritance method to use depends on actual needs and personal preferences.

5. Array operations:

Array creation and access

In JavaScript, there are several ways to create and access arrays.

Create an array:

  1. Use an array literal []to create an empty array:

    let arr = [];
    
  2. Use an array literal and provide an initial value to create an array of elements:

    let arr = [1, 2, 3];
    
  3. Create an empty array using newthe keyword and Arrayconstructor:

    let arr = new Array();
    
  4. Use newthe keyword and Arrayconstructor and provide initial values ​​to create an array of elements:

    let arr = new Array(1, 2, 3);
    

Array access:
Array elements can be accessed using indexing. Array indexes start from 0, and array elements can be accessed using square brackets or periods.

let arr = [1, 2, 3];
console.log(arr[0]);  // 输出 1
console.log(arr[2]);  // 输出 3

// 使用点号访问数组元素
console.log(arr.length);  // 输出数组的长度

Note that if a non-existent index is used to access an array element, it will be returned undefined.

let arr = [1, 2, 3];
console.log(arr[5]);  // 输出 undefined

You can also use some built-in methods of arrays to access and operate arrays, such as push, pop, shift, unshift, splice, sliceetc. These methods can perform operations such as adding, deleting, and replacing arrays.

Common methods of arrays: push, pop, shift, unshift, splice, slice, join, concat, reverse, sort, map, filter, reduce, etc.

6. Error handling:

try-catch-finally statement

throw throw exception

7. JSON:

Stringification and parsing of JSON

JSON is a way of formatting and representing JavaScript Object Notation data as strings . JSON stringification is 将 JavaScript 对象转换为 JSON 字符串的过程, however JSON 解析是将 JSON 字符串转换回 JavaScript 对象的过程.

In JavaScript, you can use JSON.stringify()the method to convert a JavaScript object into a JSON string. For example:

const obj = {
    
     name: "John", age: 25, city: "New York" };
const jsonStr = JSON.stringify(obj);
console.log(jsonStr);
// 输出: {"name":"John","age":25,"city":"New York"}

JSON parsing is the process of converting JSON strings back into JavaScript objects, which can be JSON.parse()achieved using the method. For example:

const jsonString = '{"name":"John","age":25,"city":"New York"}';
const obj = JSON.parse(jsonString);
console.log(obj);
// 输出: { name: "John", age: 25, city: "New York" }

Using JSON stringification and parsing makes it easy to process and transmit data in JavaScript, especially when interacting with back-end servers. JavaScript objects can be converted into JSON strings for transmission, and JSON can be converted into JSON strings when receiving server responses. Strings are parsed into JavaScript objects for processing.

Usage of JSON objects

8. Regular expression:

Basic syntax and matching rules of regular expressions

Regular expressions are powerful text matching tools that use concise syntax to describe patterns in strings. The following is the basic syntax and matching rules of regular expressions:

  1. Character matching:

    • Single character: Use a single character to match itself. For example, the regular expression awill match the character "a" in the string.
    • Character class: Use square brackets [] to define a character class that can match any character in the character class. For example, the regular expression [aeiou]will match any vowel in the string.
    • Range character classes: Use the hyphen - within a character class to represent a range of characters. For example, the regular expression [a-z]will match any lowercase letter.
    • Reverse character classes: Use the caret ^ within a character class to exclude certain characters. For example, the regular expression [^0-9]will match any non-numeric character.
  2. Repeat match:

    • Number of repetitions: Use quantifiers to specify the number of repetitions. Commonly used ones are:
      • *: Matches the previous element zero or more times.
      • +: Matches the previous element one or more times.
      • ?: Matches the previous element zero or one time.
      • {n}: Matches the previous element exactly n times.
      • {n,}: Matches the previous element at least n times.
      • {n,m}: Match the previous element at least n times and at most m times.
  3. Special characters:

    • \d: Matches a numeric character.
    • \w: Matches a letter, number, or underscore character.
    • \s: Matches a whitespace character.
    • \b: Matches a word boundary.
  4. Boundary matching:

    • ^: Matches the beginning of the input string.
    • $: Matches the end of the input string.
    • \b: Matches a word boundary.
  5. Grouping and capturing:

    • (pattern): Include pattern in a group.
    • (?:pattern): Only used for grouping, not capturing.

The above is only an introduction to the basic syntax and matching rules of regular expressions. Regular expressions have more functions and syntax, including the use of special characters, modifiers, backreferences, etc. In actual use, you can learn more advanced usage of regular expressions by reading more documents or tutorials.

Methods of regular expression objects

9. Strict mode:

Use "use strict" to enable strict mode

Limitations and changes in strict mode

おすすめ

転載: blog.csdn.net/m0_49768044/article/details/132523531