Notes on left ear listening style: a prototype based programming paradigm

Prototype of JavaScript

Prototype based programming is also a way of object-oriented programming. Like JavaScript is a prototype based programming idea. There is no concept of class in JavaScript. Even the class introduced in ES6 is essentially a syntactic sugar based on prototype inheritance. No new object-oriented inheritance model is introduced.

Prototype concept of Js

In js, every object has a property called proto, which is the prototype. Let's take an example to see what it is.

If we have two objects

var foo = {name: "foo", one: 1, two: 2};

var bar = {three: 3};

Then let's change the bar's "proto" property to point to foo

bar.__proto__ = foo; // foo is now the prototype of bar.

Then we can access the variables in foo if the prototype object of bar is foo

//Here the output is 1
bar.one 

// Of course, its own properties can also be accessed, and output 3
bar.three 

//In this example, we find that bar object has a copy of its prototype object, that is to say, modifying the properties in its prototype does not cause the original prototype object to be modified
bar.name = "bar";
//Output foo
foo.name; 
//Output bar
bar.name;

In JavaScript, there is also a prototype property. It needs to be explained that one is "proto" and the other is prototype

  • __proto__

    It is a pointer used by all objects to link prototypes.

  • prototype

    It is a property of a Function object in JavaScript. It can be understood that when a new Function object is used, it points to the corresponding prototype object

There are two forms of objects in JavaScript, one is Object and the other is Function

For an Object, the default value of an Object is "proto" = = Object. Prototype

For Function objects, the default Function. Proto = Function.prototype

// Object
var a = {
  x: 10,
  calculate: function (z) {
    return this.x + this.y + z;
  }
};
// Function object
function Person(){
    
}

The prototype chain of Object is easy to understand. Let's take an example

var a = {
  x: 10,
  calculate: function (z) {
    return this.x + this.y + z;
  }
};
 
var b = {
  y: 20,
  __proto__: a
};
 
var c = {
  y: 30,
  __proto__: a
};
 
// call the inherited method
b.calculate(30); // 60
c.calculate(40); // 80

The prototype chain structure of the above example is shown in the figure below

Of course, according to the js specification, we should use the official writing method to use inheritance

var b = Object.create(a, {y: {value: 20}});
var c = Object.create(a, {y: {value: 30}});

Description of official documents

  /**
      * Creates an object that has the specified prototype or that has null prototype.
      * @param o Object to use as a prototype. May be null.
      */
    create(o: object | null): any;

    /**
      * Creates an object that has the specified prototype, and that optionally contains specified properties.
      * @param o Object to use as a prototype. May be null
      * @param properties JavaScript object that contains one or more property descriptors.
      */
    create(o: object | null, properties: PropertyDescriptorMap & ThisType<any>): any;

For Function objects, let's look at the following code

// A writing method of constructor
function Foo(y) {
  this.y = y;
}
 
// Modify the prototype of Foo and add a member variable x
Foo.prototype.x = 10;
 
// Modify the prototype of Foo and add a member function calculate
Foo.prototype.calculate = function (z) {
  return this.x + this.y + z;
};
 
// Now, we use the Foo prototype to create b and c
var b = new Foo(20);
var c = new Foo(30);
 
// Call the method in the prototype to get the correct value
b.calculate(30); // 60
c.calculate(40); // 80

The layout of its prototype chain is shown in the figure below,

First, the Foo function object will have a prototype property, which will be automatically generated by the system. The constructor property of the object will be changed to point to itself by default, that is, the Foo object. The. proto? Of the Foo function object points to Function.prototype. The. proto? Of its Foo.prototype object points to Object.prototype.

The above association can be verified by the following methods

b.__proto__ === Foo.prototype, // true
c.__proto__ === Foo.prototype, // true
 
b.constructor === Foo, // true
c.constructor === Foo, // true
Foo.prototype.constructor === Foo, // true
 
b.calculate === b.__proto__.calculate, // true
b.__proto__.calculate === Foo.prototype.calculate // true

After understanding the above knowledge, take a look at the object-oriented play of js.

Defining parent class

//Define human class
var Person = function (fullName, email) {
  this.fullName = fullName;
  this.email = email;
  
  this.speak = function(){
    console.log("I speak English!");
  };
  this.introduction = function(){
    console.log("Hi, I am " + this.fullName);
  };
}

Defining subclasses

//Define Student class
var Student = function(fullName, email, school, courses) {

   //Use call to change this point, and point the method attribute this in the parent class to Student
  Person.call(this, fullName, email);

  // Initialize our Student properties
  this.school = school;
  this.courses = courses;
  
  // override the "introduction" method
  this.introduction= function(){
  console.log("Hi, I am " + this.fullName + 
        ". I am a student of " + this.school + 
        ", I study "+ this.courses +".");
  };
  
  // Add a "exams" method
  this.takeExams = function(){
    console.log("This is my exams time!");
  };
};

Use prototype chain to inherit and associate objects

// Create a Student.prototype object that inherits 
// from Person.prototype.
Student.prototype = Object.create(Person.prototype); 

// Set the "constructor" property to refer to Student
Student.prototype.constructor = Student;

Verify that we succeeded in inheriting

var student = new Student("Ai Xue xi",
    "aixuexi@hotmail.com",
    "XYZ University",
    "Computer Science");
student.introduction();
student.speak();
student.takeExams();

// Check that instanceof works correctly
console.log(student instanceof Person);  // true
console.log(student instanceof Student); // true

class is introduced into ES6, which is more convenient for us to use inheritance, which is much clearer and more convenient than ES5's implementation of inheritance by modifying the prototype chain.

class A{
    constructor(name,age){
        this.name = name;
        this.age = age
    }
}

class  B extends A{
    constructor(name,age,addr){
        super(name,age);
        this.addr = addr
    }
}

var a = new A("1",2);
var b = new B("!",2,"3");
console.log(b instanceof B)
console.log(b instanceof A)

Keywords: Programming Javascript Attribute

Added by willchoong on Sun, 05 Jan 2020 16:19:03 +0200