A brief introduction of class

The origin of the class

  • In JS, the traditional way to generate instance objects is through constructors, as shown below
  Before ES6, you could only instantiate objects using functions

  function Point(x,y){

   this.x=x;

   this.y=y;

  }

  Point.prototype.toString=function(){

   return '('+this.x+', '+this.y+') '

  }

  var one=new Point(1.2)

  console.log(one.toString());/ / (1, 2)

  

  // In ES6 you can instantiate objects using classes

  class Person{

   constructor(x,y) {

       this.x=x;

      this.y=y;

   }

   toString(){

    return '('+this.x+', '+this.y+') '

   }

  }

  var two=new Person(3.4)

  console.log(two.toString());/ / (3, 4)

Copy the code
  • In essence, the data type of a class is a function, and the class itself is a constructor pointing to itself
  • In essence, all methods of a class are defined on the class's Prototype property
  • That is, the constructor of an instance of the class === the constructor of the prototype of the class
  class Point{}

  // 1. The data type of the class is a function

  console.log(typeof Point) // function

  // 2. The constructor on the prototype chain of the class points to the class

  console.log(Point===Point.prototype.constructor)  //true

  // 3. An instance of a class can call its methods because its methods are defined on the prototype of the class

  // So instances of classes can find methods to call through the prototype chain

  

  // 4. The constructor of an instance of a class equals the constructor of the prototype of the class

  console.log(new Point().constructor === Point.prototype.constructor) //true

  

  // 5. Cannot declare classes with the same name. Identifier 'Point' has already been declared

  class Other{

   constructor(name) {

       this.name=name;

   }

   toValue(){

    return this.name+'On the prototype chain'

   }

  }

  var one=new Other('hh')

  console.log(one.toValue()) //hh on the prototype chain

Copy the code
  • Methods defined inside a class are not enumerable by default! Methods defined externally using stereotypes are enumerable by default
  // 1. Methods defined internally by a class are non-enumerable by default

  class Other{

   constructor() {

   }

   toValue(){

    return this.name+'On the prototype chain'

   }

  }

  // 1. Methods defined on the prototype chain of a class are enumerable

  // Yes! Because it is attached to the prototype chain, it can be accessed directly, unless object.defineProperty is set to non-enumerable

  Other.prototype.getData=function(){}

  // ["getData"]

  console.log(Object.keys(Other.prototype))

Copy the code

Constructor constructor method

  • The constructor method is the default method of the class and is automatically called when an object instance is generated using the new command
  • A class that defaults to a constructor method will default to an empty constructor method even if no declaration is displayed
  • The constructor method returns an instance object of the class by default, but you can explicitly use return to return something else
 // 1. A class with no constructor function

 class One{}

 console.log(new One()) //One

 // 2. A class with an empty constructor function (equivalent to One)

 class Two{

  constructor() {}

 }

 console.log(new Two()) //Two

 // 3. A class whose constructor function is not empty

 class Three{

  constructor() {

   console.log('constructor')

  }

 }

 console.log(new Three()) // Print constructor, Three

 // 4. The constructor returns other objects

 class Four{

  constructor() {

   return {name:'a'.age:10}

  }

 }

 console.log(new Four()) //{name: "a", age: 10}

Copy the code
  • One difference between a class and a function is that the class must be called with new or an error will be reported! Functions can be executed without using new
  • But for instance methods of a class, you can call them directly from the class
 class Func{

  static a(){

   return 'ddds'

  }

 }

 console.log(Func.a())

Copy the code

Instances of the class

  • Class instance attributes are defined on the stereotype. Unless the class is declared in the constructor!
  class Point{

   constructor(x,y){

    this.x=x;

    this.y=y;

   }

   a(){

    return 'Defined on the prototype chain'

   }

  }

  var p=new Point(2.3)

  The 1. X,y attributes are defined in the constructor, so the instance can be obtained directly

  console.log(p.hasOwnProperty('x'))//true

  console.log(p.hasOwnProperty('y'))//true

  // The 2.a method is not defined in the constructor and needs to be retrieved through the prototype chain of the instance

  console.log(p.hasOwnProperty('a'))//false

  console.log(p.__proto__.hasOwnProperty('a')) //true

Copy the code
  • Within a class, all instances share a prototype object
 class Point{}

 var one=new Point()

 var two=new Point()

 // 1. Two instance objects from the same class new share a prototype object

 console.log(one.__proto__===two.__proto__)//true

 // 2. Add a method to the prototype of one instance, and the other instance will have that method

 one.__proto__.add=function(){

  return 'add'

 }

 console.log(one.add()) // add

 console.log(two.add()) // add

Copy the code

Getter and setter

  • You can use the get and set keywords inside a class to set the store and value functions for a property
  • The set and get functions are set on the Descriptor object of the function
 class one{

  a='Use getter,setter function'

  get a(){

   return this.a;

  }

  set a(val){

   this.a=val;

  }

 }

 var p=new one()

 console.log(p.a) // Use getter,setter functions

 p.a='change'

 console.log(p.a) / / change

 

 // Get the Descriptor property of the object

 var desc=Object.getOwnPropertyDescriptor(one.prototype,'a')

 console.log(desc) //{enumerable: false, different: true, get: ƒ, set: ƒ}

 console.log('get' in desc) // true

 console.log('set' in desc) // true

Copy the code

The class expressions

  • The class class can also be defined as an expression. Note that:
 var outer=class inner{

  getName(){

   // return this; //inner {}

   return inner.name;

  }

 }

 Outer is the outer name of the class, which must be used outside the class

 var c=new outer()

 console.log(c.getName()) // inner

 // 2. Inner is the inner name of the class and can only be used inside the class

 // inner.getName() //ReferenceError: inner is not defined

Copy the code
  • There is another class expression that executes immediately, but it is not desirable and is used too often
    let person=new class{

    constructor(name) {

      this.name=name;

      }

      getName(){

        console.log(this.name)

      }

} ('yiye')

    person.getName() //yiye

Copy the code

Pay attention to the point

  1. As long as it is in a class or module, the default is strict mode. You do not need to use 'use strict' to specify the operation mode
  2. There is no variable promotion in the class (because you must ensure that the subclass comes after the parent!) class one{}; class two extends one{};
  3. The class also has the name attribute of the function, and you can get the name of the class from class.name
  4. The [symbol. iterator] method of a class is the iterator used by default when the class is iterated
 class Point{

  constructor(... args) {

      this.args=args

  }

* [Symbol.iterator](){

   for(let arg of this.args){

    yield arg;

   }

  }

 }

 var p=new Point(1.3.'d')

 for(var item of p){

  console.log(item); //1 3 d

 }

Copy the code
  1. This refers to an instance of the class by default, but sometimes an error is reported
 class one{

  constructor(name) {

      this.name=name;

  }

  getName(){

   return this.name;

  }

 }

 var a=new one('yiye')

 var {getName}=a; // Get the getName method of the · object

 

 // Only the getName method is destructed, and this of the method refers to this of the runtime environment

 // console.log(getName()) // Cannot read property 'name' of undefined

 // Add the name attribute.

 var name='hh'

 console.log(getName()) // Cannot read property 'name' of undefined

 // This is because we use strict mode inside the class, so this actually refers to undefined

Copy the code
  • Because the word limit is exceeded, so it is divided into several ~
  • Note: since I did not pay attention to the specification of the first letter of the class, so changed once, if there is a problem with the above code to see the class name

This article refers to ruan Yifeng ES6 tutorial