Regular study notes, including ES6, Promise, Node.js, Webpack, HTTP Principles, Vue buckets, and possibly more Typescript, Vue3, and common interview questions.

The constructor

Functions called with the new keyword are called constructors.

Constructors typically have two properties, one on the stereotype and one on the instance.

function Animal(name) {
  this.name = name;
  this.arr = [1.2.3]}let a1 = new Animal('dog');
let a2 = new Animal('the cat');
console.log(a1.arr === a2.arr); // false
Copy the code

Instance properties point to a different storage space (heap memory), so the output is false, which is the property of the instance itself.

By defining properties on the stereotype, you can make an instance own properties on the stereotype

Animal.prototype.address = {location:'home'}
console.log(a1.address === a2.address) // true
Copy the code

Prototype and prototype chain

First we need to understand the relationship between classes (constructors), stereotypes, and constructors.

  • Every class (function) hasprototypeAnd the property value is oneObject
  • An object is born with a propertyconstructor, pointing to the class itself
  • Each object (Ordinary objectsprototypeThe instancefunctionAnd so on__proto__
function Foo() {... };let f1 = new Foo();
Copy the code

__proto__ : When accessing a property of an object that does not have the property, the object to which its __proto__ attribute points will be accessed. If the parent object does not have the property, The __proto__ attribute of the parent object points to the parent object. If it doesn’t find the parent object, the parent object’s __proto__ attribute points to the parent object. Until the top of the prototype chain is null, truly null.

Prototype: contains properties and methods that can be shared by all instances of a particular type, i.e. objects instantiated by this function can find common properties and methods. When any function is created, the default is to create its prototype object as well.

Constructor: Points to the object’s constructor. Each object has a constructor. If the object itself does not have a constructor attribute, it looks up the prototype chain via __proto__, finds the constructor in the prototype chain, determines its direction, and inherits.

This is my personal understanding of the prototype chain lookup mechanism.

First, an instance’s __proto__ will always point to its constructor’s prototype property (F.__proto__ === fn. prototype), and the constructor and all of its parent classes (Fn, Function, Object) will point to function. prototype. __proto__ points to Object.prototype, and function.prototype. __proto__ points to object. prototype. Object.prototype.__proto__ points to null, which is the end of the prototype chain.

For prototype chains, see the diagram above, which more intuitively represents the relationship between prototype, __proto__, and constructor. You can draw them if you want.

Class inheritance

A constructor is a class.

function Animal(name) {
  this.name = name;
  this.eat = 'meat';
}
Animal.prototype.address = {location: 'the mountains'}
function Tiger(name) {
  this.name = name;
  this.age = 10;
}
Tiger.prototype.say = function () {
  console.log('speak');
}
Copy the code

Here we simulate a parent Animal and a child Tiger

  1. Inherits properties on the parent instance

    All we need to do is add a.call to the subclass to change the orientation of this

    function Tiger(name) {
      this.name = name;
      this.age = 10;
      Animal.call(this); // Point this from the parent class to the child class so that the child class inherits the attributes from the parent class.
    }
    let tiger = new Tiger();
    console.log(tiger.eat); / / to eat meat
    Copy the code
  2. Inherits a method from a superclass stereotype

    In doing so, we only inherit properties from the parent instance, not from its prototype.

    console.log(tiger.address); // undefined
    Copy the code

    Here we have several solutions

    • Prototype.__proto__ = subclass. prototype

      The prototypes of our subclasses and superclasses point to different methods and objects, respectively. So we in order to make the prototype of the subclass inherits the parent class method on the prototype, can let a subclass of the prototype. __proto__ pointing to the prototype of the parent.

      Tiger.prototype.__proto__ = Animal.prototype;
      console.log(tiger.address); // {location: 'mountain '}
      Copy the code

      So we implement one of the inheritance methods.

    • Object.create

      The object.create () method creates a new Object, using an existing Object to provide the __proto__ of the newly created Object.

      Tiger.prototype = Object.create(Animal.prototype);
      console.log(tiger.address); // {location: 'mountain '}
      Copy the code
    • Object.setPrototypeOf

      Use the object.setProtoTypeof () method to set the Prototype (that is, the internal [[Prototype]] property) of a given Object to another Object or null.

      Object.setPrototypeOf(Tiger.prototype, Animal.prototype);
      Copy the code

    (Note: the above methods need to be added before the subclass’s prototype method binding.)

    This way we can’t pass arguments to the parent class, only to the subclass.

Classes in ES6

First of all, ES6 and ES5 are implemented in the same way, using the prototype chain.

class Animal {
  constructor(name) {
    this.name = name;
    this.eat = 'meat';
  }
  say() {
    console.log('say'); }}Copy the code

This is the simplest kind of implementation.

But ES6 classes differ from ES5 in a few ways

  • Classes may not be called as functions.

    Animal() // Class constructor Animal cannot be invoked without 'new'
    Copy the code

    ES6 classes need to be instantiated using new as the keyword

    Similarly, if we call the method on the prototype, we can instantiate the class and call it directly.

    let a = new Animal();
    a.__proto__.say(); // say
    Copy the code

    (Note: In the ES6 specification, this does not exist if the method on the prototype is called separately.)

    Let’s say we instantiate the method directly from the prototype

    // Temporarily modify the say() method on the Animal class, and then change it back after testing
    say() {
      console.log(this);
    };
    
    let say = a.__proto__.say;
    say(); // undefined
    Copy the code

    The result returned is undefined

  • Include static methods (static properties in ES7)

    ES6 allows classes to have private methods (private properties in ES7)

    class Animal {
      // ES6
      static flag() {
        return 'test';
      }
      // ES7
      static flag = 'test'
    }
    console.log(Animal.flag()) // test
    Copy the code

    (Note: in ES6 environment, ES7 writing cannot be used)

    Call, you need to directly use the class to call, instance cannot call.

  • Inheritance is implemented using the extends keyword

    Extends implements inheritance directly.

    class Tiger extends Animal {}
    let t = new Tiger('the tiger')
    t.say(); // say
    console.log(t.eat); / / to eat meat
    console.log(t.name); / / the tiger
    Copy the code

    First, the methods and stereotypes of the parent class are inherited directly from the child class.

    The passed value tiger is then passed directly to the parent class’s constructor, which outputs the result directly.

    class Tiger extends Animal {
        constructor(){}/ / an error
    }
    Copy the code

    One more thing to note here is that the parent class has its own constructor and the subclass cannot define constructor

    If you want to do this, you need to use the keyword super.

    class Tiger extends Animal {
      constructor(name){ // Animal.call(this, name) 
        super(name)
      }
    }
    Copy the code

    (Note: you can go to Babel to see the implementation of class in ES6.)

This article was created by Mo Xiaoshang. If there are any problems or omissions in the article, welcome your correction and communication. You can also follow my personal site, blog park and nuggets, AND I will upload the article to these platforms after it is produced. Thank you for your support!