function

1. Understand features

  • In general, a function is a “subroutine” that can be called from external code (or, in the case of recursion, from an internal function).
  • In JavaScript, functions are first-class objects because they can have properties and methods like any other object, and can be assigned to variables or passed as arguments to other functions. They differ from other objects in that functions can be called. In short, they are Function objects.)
  • If a function does not use a return statement, it returns undefined by default.
  • When a function is called, the values passed to it are called its arguments (pass-by-value), and the corresponding function arguments are called parameters. If the argument is a variable that contains the original value (number, string, or Boolean), the internal change of the corresponding parameter will not change the value of the argument after the return. If the argument is an object reference, then the corresponding form and the argument point to the same object. If the function internally changes the value of the corresponding parameter, the value of the object to which the argument points will also change after the return), so there is often a deep-copy problem
  • Each call also has another value – the context of the call – which is the value of the this keyword
  • When a function is defined nested within another function, it can then access any variable in the scope in which it was defined (this is a javascript function that constitutes a closure).

2. Function definition

2.1. Function Declaration (function statement)

function name([param[, param[, ... param]]]) {
    statements
}
// name Specifies the name of the function.
// The name of the argument that param passes to the function. A function can have up to 255 arguments.
// statements The statements that make up the function body.
Copy the code

The function declaration statement is “advanced” to the top of the external script or external function scope, so it can be called by code that appears before it is defined.

2.2. Function expressions

var myFunction = function name([param[, param[, ... param]]]) {
    statements
}
// name Specifies the function name, which can be omitted. When the function name is omitted, the function becomes anonymous.
// Param and statements are used the same as in function declarations.
Copy the code

Function expressions are not promoted, so they cannot be called before definition.

2.3. Arrow function expressions

([param] [, param]) => { statements }

param => expression

// Param Parameter name. The zero parameter needs to be denoted by (). No parentheses are required when only one parameter is used (for example, foo => 1).
// Statements or expression Multiple statements need to be enclosed in braces, but a single expression does not. The expression is also the implicit return value of this function.
Copy the code

3. Function properties and methods

Because functions are special objects in javascript, they can also have properties and methods.

3.1. The length attribute

The length attribute of a function is read-only and represents the number of arguments to the function.

3.2. The prototype properties

  • Each function contains a Prototype property, which is a reference to an object called the ‘prototype Object’.
  • Each function contains a different prototype object.
  • When a function is used as a constructor, the newly created object inherits properties from the prototype object.

3.3. Call () method and apply () method

For more information, see this article juejin.im/post/684490…

3.4. The bind () method

Same as above

3.4. The toString () method

Method returns a string that is related to the syntax of the function declaration statement. Most (but not all) implementations of the toString() method return the complete source code for the function.

Constructor

A constructor is a function designed to generate an instance object. It is an object template that describes the basic structure of an instance object.

The constructor is just an ordinary function

var Animal = function () {
  this.name = 'dog';
};
Copy the code

In the above code, Animal is the constructor. To distinguish them from normal functions, the first letter of the constructor name is usually capitalized.

Constructors have two characteristics.

  • The this keyword is used inside the function body to represent the object instance to be generated.
  • To generate an object, you must use the new command.

1. The new command

1.1. Effect of

The purpose of the new command is to execute the constructor and return an instance object.

var Animal = function () {
  this.name = 'dog';
};

var v = new Animal();
v.name // dog
Copy the code

Resolution:

  • The above code uses the new command to make the constructor Animal generate an instance object, which is stored in the variable v. This newly generated instance object gets the name property from the Animal constructor.
  • When the new command is executed, the this inside the constructor represents the newly generated instance object. This. Name means that the instance object has a name attribute with the value dog.

If you forget to use the new command and call the constructor directly, the constructor becomes a normal function and does not generate an instance object.

1.2. Principle of the new command

When you use the new command, the functions that follow it perform the following steps in turn.

  • 1. Create an empty object as the object instance to be returned.
  • 2. Point the null object to the constructor’s prototype property.
  • 3. Assign the empty object to the this keyword inside the function.
  • 4. Start executing the code inside the constructor.

In the constructor, this refers to a newly generated empty object on which all operations on this will take place. Constructors are called “constructors” because the purpose of the function is to manipulate an empty object (this object) and “construct” it into what it needs to look like.

function _new() {
    var obj = new Object(a);// 1. Create an empty object as the object instance to be returned.
    var Constructor = [].shift.call(arguments); // Fetch the constructor.
    obj.__proto__ = Constructor.prototype; // 2. Point the null object to the constructor's prototype property.
    var ret = Constructor.apply(obj, arguments); // 3. Assign the empty object to the this keyword inside the function. 4. Start executing the code inside the constructor.
    return typeof ret === 'object' ? ret : obj;
}
Copy the code

object

The design of JavaScript is a simple object-based paradigm. An object is a collection of properties. A property contains a name and a value. The value of an attribute can be a function, in which case the attribute is also called a method. In addition to those predefined in the browser, you can also define your own objects.

For object basics, see these three articles

  • Developer.mozilla.org/zh-CN/docs/…
  • Developer.mozilla.org/zh-CN/docs/…
  • Developer.mozilla.org/zh-CN/docs/…

1. Create objects using constructors

  • Define the type of an object by creating a constructor.
  • Create an object instance with new.

To define an object type, create a function for the object type to declare the type’s name, properties, and methods. For example, if you want to create a type for a car and call such an object car and have the properties make, Model, and year, you can create the following function:

function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
// Note that the value passed to the function is assigned to the property of the object by using this.
Copy the code

You can create any number of CAR objects by calling new. Such as:

var kenscar = new Car("Nissan"."300ZX".1992);
var vpgscar = new Car("Mazda"."Miata".1990);
// This is what the constructors discussed above do
Copy the code

2. The Object. The create () method

Objects can also be created using the object.create () method. This method is useful because it allows you to select a prototype object for the object you create without defining a constructor.

var Animal = {
  type: "Invertebrates".// Attribute default value
  displayType : function() {  // The method used to display the type attribute
    console.log(this.type); }}// Create a new animal -- animal1
var animal1 = Object.create(Animal); // Animal is a common object, not a constructor. We can create new animals.
animal1.displayType(); // Invertebrates
Copy the code

Prototype chain (inheritance)

Every javascript object (except null) is associated with another object. The other object is what we call a stereotype, from which every object inherits its properties.

  • Objects created through Object directness all have the same prototype Object and can be referenced to the prototype Object through object.prototype.
  • The prototype of an object created through new and a constructor call is the value of the constructor’s Prototype property.
  • Objects created with new Object() also inherit from object.prototype.
  • Similarly, the object created with new Array() is array.prototype; The prototype of an object created with new Date() is date.prototype.
  • The built-in constructors (Array, Date, etc.) all have a prototype that inherits from object.prototype, so the properties of a Date Object created with new Date() inherit from both date.prototype and object.prototype. This is called chained inheritance, and it’s called a prototype chain.

Each instance object has a private property (called _ _ proto _ _) that points to its constructor’s prototype. The prototype object also has a prototype object of its own (_ _ proto _ _), layered up until an object’s prototype object is null. By definition, NULL has no stereotype and serves as the last link in the stereotype chain.

1

All functions have a special property called Prototype

1.1 Let’s open the browser F12, look at the console, and enter the following code

function wqh(){};
console.log( wqh.prototype );
Copy the code

You can see that the prototype output is an object with two properties: Constructor and _ _ proto _ _

Let’s click on _ _ proto _ _ to see more

We know that an Object’s _ _ proto _ _ refers to its constructor’s prototype

Now let’s add a new property to the function a’s prototype object

function wqh(){};
wqh.prototype.age = 18
console.log( wqh.prototype );
Copy the code

Let’s take a look at the output

1.3 Construct an instance object using the new operator

function wqh(){};
wqh.prototype.age = 18;
var good = new wqh();
good.height = 178;
console.log( good.age );
console.log( good );
Copy the code

Let’s take a look at the output

The _ _ proto _ _ property of the new instance is exactly the same as the prototype property of the WQH constructor. So the instance object’s _ _ proto _ _ points to its constructor’s prototype.

The layered _ _ proto _ _ is the prototype chain. When there is no age attribute on the instance, it will go to the _ _ proto _ _ stereotype, and if there is no age attribute, it will go to the upper level, which is called the stereotype chain lookup.

2. Prototype Chain (inheritance)

According to the discussion above, draw a picture

So when we write a constructor, if we want to write some common (inheritable) properties or methods, we can write it on the prototype.

Another benefit is that it saves memory; For example, if you write a method on a constructor, if there are 100 instances of new, the method will be constructed 100 times. If you write the method on a prototype of the constructor, it will only be constructed once. The instance of new will look for the method on the prototype chain, saving much memory.

3. Is it really inheritance?

Inheritance is a term I first learned from Java, but is this prototype chain in JS inheritance?

To quote JavaScript You Don’t Know: Inheritance means copying operations. However, JavaScript does not copy the properties of an object by default. Instead, JavaScript simply creates an association between two objects, so that one object can access the properties and functions of the other object through a delegate.

But we’ll always talk about inheritance, because it means the same thing at the level of understanding, so that you can talk to non-javascript programmers, and when you talk to js programmers who are in the same gate, you have to talk about prototype chains and prototype chain lookup, so it’s more accurate.

class

The concept of a class: an abstraction of a set of objects that have the same properties and behavior. Javascipt syntax does not support “class”

  • From above we know that JavaScript uses stereotypes to ‘inherit’ : each object ‘inherits’ properties and methods from its prototype object.
  • There are no traditional classes in JavaScript that are used in languages like Java as blueprints for creating objects, and prototypes’ inherit ‘only to handle objects.
  • But when we use it, we find that the prototype ‘inheritance’ can mimic the inheritance of the classic class. To introduce traditional classes into JavaScript, the ES2015 standard (ES6) introduced class syntax: syntax sugar based on prototype ‘inheritance’.

So to summarize: classes in JS (after ES6) are still prototypes and constructors written based on the ‘inheritance’ of the prototype chain. Just for the sake of syntax succinct, general purpose, easy to understand (understanding analogy understanding prototype chain is much easier) encapsulated syntax.

1. Constructor writing

// Define the constructor
// Here follows a common programming convention: in a sense, the definition constructor defines the class, and the first letter of the class name should be capitulated.
function People(name, age) {
    this.name = name;
    this.age = age;
};
People.prototype.showName = function () {
    console.log(this.name);
};

// Use the constructor
var p1 = new People('wqh'.18);
p1.showName();
var p2 = new People('w'.19);
var p3 = new People('q'.20);
console.log(p1, p2, p3);
Copy the code

Looking at the output, we find:

  • The _ _ proto _ _ of different instances of new all point to the same stereotype.
  • The constructor on the prototype all points to the same constructor, People.
  • The methods written on the People constructor are ‘inherited’ by the instance.
  • Only properties written on the Prototype prototype are ‘inherited’ (common properties), the rest are private.

Add a mistake prone point

function People(name, age) {
    this.name = name;
    this.age = age;
};
People.prototype = {
    showName: function () {
        console.log(this.name); }}// Use the constructor
var p1 = new People('wqh'.18);
p1.showName();
var p2 = new People('w'.19);
var p3 = new People('q'.20);
console.log(p1, p2, p3);
Copy the code

We find that when Prototype is redefined as an object, this newly defined prototype object does not have a constructor property, and therefore class instances do not have a constructor property.

The constructor property

  • Each prototype object contains a unique non-enumerable property, constructor, whose value is a function object.
  • In the previous code, we added a new method to the prototype object, rather than redefining the object.
  • So there is a predefined constructor property in the constructor prototype, which means that objects typically inherit constructor that refers to their constructor. Since constructors are the ‘public identity’ of the class, this constructor property provides the class for the object
  • So when people.prototype = {}, this breaks the prototype and the prototype chain.

The solution

Explicitly add a constructor to the prototype

function People(name, age) {
    this.name = name;
    this.age = age;
};
People.prototype = {
    constructor: People,
    showName: function () {
        console.log(this.name); }}// Use the constructor
var p1 = new People('wqh'.18);
p1.showName();
var p2 = new People('w'.19);
var p3 = new People('q'.20);
console.log(p1, p2, p3);
Copy the code

2. The class notation

class People {
    constructor (name, age) {
        this.name = name;
        this.age = age;    
    }
    
    showName () {
        console.log(this.name); }};// Use the constructor
var p1 = new People('wqh'.18);
p1.showName();
var p2 = new People('w'.19);
var p3 = new People('q'.20);
console.log(p1, p2, p3);
Copy the code

Pay attention to the point

  • This constructor does not act the same way as constructor in the previous constructor. Constructor functions can pass arguments. Class does not pass arguments. However, we can pass arguments with new.
  • The constructor method is the default method of the class and is automatically called when an object instance is generated with the new command. A class must have a constructor method. If it is not explicitly defined, an empty constructor method will be added by default.
  • The prototype property of the constructor survives on the “class” in ES6. In fact, all the methods of the class are defined on the prototype property of the class.
class People {
  constructor() {
    // ...
  }
  showName() {
    // ...}}/ / is equivalent to
People.prototype = {
  constructor() {},
  showName(){}};// Calling a method on an instance of the class is essentially calling a method on the prototype.
// p2.constructor === People.prototype.constructor // true
Copy the code
  • In addition to being defined above this in the constructor() method, instance properties can also be defined at the top level of the class.
class People {
    hello = 'hello';
    world = 'world';
    constructor (name, age) {
        this.name = name;
        this.age = age;    
    }
    
    showName () {
        console.log(this.name); }};// Use the constructor
var p1 = new People('wqh'.18);
p1.showName();
var p2 = new People('w'.19);
var p3 = new People('q'.20);
console.log(p1, p2, p3);
Copy the code

See class for more informationes6.ruanyifeng.com/#docs/class

It is often said that ‘everything in JS is an object’ (excluding basic types). We started by saying that functions are special objects, so everything from functions to classes are objects, and classes are functions because the data types of classes are functions. So in the JS world, everything is real as an object.