Object orientation is a programming idea that we implement through classes (constructors) and objects, satisfying three specific requirements: encapsulation, inheritance, and polymorphism.

encapsulation

Encapsulates the function that creates the object

Encapsulation is to encapsulate the code that implements a function into a function. Later, to implement the function, you only need to execute the function. Low coupling, high cohesion.

Now we wrap the properties and methods into an object:

Var person = new Object(); // Add the attribute and method person.name ="Iron Man";
		person.sex = "Male";
		person.showName = function(){
			alert("My name is."+ this.name); My name is Iron Man} person.showsex =function(){
			alert("My gender is"+ this.sex); // My gender is male} person.showname (); person.showSex();Copy the code

If we want to create an object with a different name and gender, we need to write the above code again:

Var person2 = new Object(); // Add the attribute and method person2.name =The Scarlet Witch.;
		person2.sex = "Female";
		person2.showName = function(){
			alert("My name is."+ this.name); My name is Scarlet Witch} person2.showsex =function(){
			alert("My gender is"+ this.sex); // My gender is female} person2.showname (); person2.showSex();Copy the code

If we want to create multiple objects, it can be very cumbersome to write, so we need to encapsulate the object creation function to solve the problem of code duplication.

		function createPerson(name, sex){
			var person = new Object();
			person.name = name;
			person.sex = sex;
			person.showName = function(){
				alert("My name is" + this.name);
			}
			person.showSex = function(){
				alert("I am" + this.sex + "The");
			}
			return person;
		}
Copy the code

Then generate the instance object, which is equivalent to calling the function:

		var p1 = createPerson("Iron Man"."Male"); p1.showName(); // My name is Iron Man p1.showsex (); Var p2 = createPerson(The Scarlet Witch.."Female"); p2.showName(); // My name is Scarlet Witch p2.showsex (); // I am a womanCopy the code

The above process can be analogous to opening a factory to produce yogurt: Step 1: Raw materials are needed; Step 2: processing yogurt; Step 3: factory sale; We declare the empty object with var as the first raw material, add properties and functions as the second processing, and return the object as the third factory. This function which conforms to the above steps 1, 2 and 3 is called factory function, and this idea of designing functions is called factory design pattern.

Call a function with new

The official way to create an object is through the new method. When we don’t use new to create an object, the this inside the function points to the window.

		function show(){ alert(this); //[object Window] } show();Copy the code

So when we assign this. Name to XXXX inside the function, we can print XXXX through window.name, because if the function has no owner, its owner is the window object.

		function show(){ alert(this); //[object Window] this.name ="xxxx"; } show(); alert(window.name); //xxxxCopy the code

But if this function is called with the new operator, then this in this function will refer to the newly created object.

		function show(){ alert(this); //[object Object] } var obj = new show();Copy the code

When we call a function using the new operator, the following two steps are automatically generated: 1. 3, factory operation: return this return this; .

		function show(){ // this = new Object(); alert(this); //[object Object] this.name ="xxxx";
			// returnthis; } var obj = new show(); alert(obj.name); //xxxxCopy the code

So now let’s change the function we created earlier, call it all through new, and change the person in the function to this.

		function createPerson(name, sex){
			this.name = name;
			this.sex = sex;
			this.showName = function(){
				alert("My name is" + this.name);
			}
			this.showSex = function(){
				alert("I am" + this.sex + "The");
			}
		}
		var p1 = new createPerson("Iron Man"."Male"); p1.showName(); // My name is Iron Man p1.showsex (); Var p2 = new createPerson(The Scarlet Witch.."Female"); p2.showName(); // My name is Scarlet Witch p2.showsex (); // I am a womanCopy the code

The constructor

We call these functions that create objects constructors. (Function is used to construct objects.)

		function Person(name, sex){
			this.name = name;
			this.sex = sex;
		}
Copy the code

To distinguish it from other functions, we capitalized the constructor. Official constructors: Array, Object, Date.

Object, Array and Date created by new are function functions in nature. And all the objects that are created by this function, the methods of the objects are the same, arr1.push === arr2. Push returns true.

var arr = new Array(); var obj = new Object(); var d = new Date(); alert(typeof Array); / / typefunctionfunctionCopy the code

But object methods generated by calling functions are unrelated to each other and do not reflect instances of the same prototype object. alert(p1.showName === p2.showName); The return value is false.

		var arr1 = new Array(10, 20, 30);
		var arr2 = new Array(40, 50, 60);
		alert(arr1.push === arr2.push); //true
Copy the code

We declare two arrays

		var arr1 = [10, 20, 30, 40, 50];
		var arr2 = [60, 70, 80, 90, 100];
Copy the code

A function that adds a sum to an array

		arr1.sum = function(){
			var res = 0;
			for(var i = 0; i < this.length; i++){
				res += this[i];
			}
			return res;
		}
Copy the code

Sum will output the sum of arr1 as 150, but arr2.sum will return an error indicating that arr1.sum is not a function. Since ARr1 and ARR2 are separate objects, add a method to ARr1 and ARR2 will not own the method. So after we generated the object by calling the function new, their methods were independent of each other.

alert(arr1.sum == arr2.sum); //false
Copy the code

Each instance object has its own copy of properties and methods. This not only fails to share data, but is also a huge waste of resources.

Prototype prototype

Prototype object: all properties and methods that need to be shared by instance objects are put in this object, and those that don’t need to be shared are put in constructors. To simulate the class.

So if we want arr2 to have summation functions, we need to rewrite arr2.sum, which is wasteful. We want objects to share a method, so we need to introduce prototype. In JS everything is an object and functions are objects. Every function that is created has an official built-in property called a prototype object. We print show.protoype to get the result [Object object].

		function show(){ } alert(show.protoype); //[object Object]Copy the code

All properties and methods that instance objects need to share are placed in this object; Properties and methods that do not need to be shared are stored in constructors.

If we want the object created by this function to have a common set of functions, then we should add this set of functions to the function’s prototype. So if we want both arrays to have summation methods, we need to add this method to the Array prototype.

		Array.prototype.sum = function(){
			var res = 0;
			for(var i = 0; i < this.length; i++){
				res += this[i];
			}
			return res;
		}
Copy the code

Now both ARr1 and ARr2 can use this function, and arr1.sum == arr2.sum, they both use the same method from the prototype.

alert(arr1.sum()); //150 alert(arr2.sum()); //400 alert(arr1.sum == arr2.sum); //true
Copy the code

We can use a hybrid approach, where a user-defined constructor encapsulates a function that creates an object and calls the same method.

		function Person(name, sex){
			//this = new Object();
			this.name = name;
			this.sex = sex;
			//returnthis; } / / function, it is necessary to add in the function prototype prototype Person. Prototype. ShowName =function(){
			alert("My name is" + this.name);
		}
		Person.prototype.showSex = function(){
			alert("I am" + this.sex + "The");
		}
		var p1 = new Person("Iron Man".'male');
		var p2 = new Person(The Scarlet Witch.."Female"); p1.showName(); // My name is Iron Man p1.showsex (); // I am male p2.showname (); // My name is Scarlet Witch p2.showsex (); // I am female alert(p1.showname == p2.showname); //true
Copy the code

Examples of object-oriented programming

Now we’re going to test 100 different brands of cars, and record their performance on the road.

Create a constructor that can construct various models

		function Car(type, name, speed){
			this.type = type;
			this.name = name;
			this.speed = speed;
		}
Copy the code

Add features to the Car prototype: let the Car run on the road, calculate the speed.

		Car.prototype.run = function(the road) {alert (` one${this.type}The brand of${this.name}Series, speed is${this.speed}Km /h of the car, running at length zero${road.length}km${road.name}The final result is${road.length / this.speed}Hours `); }Copy the code

Create a constructor that can construct various roads

		function Road(name, length){
			this.name = name;
			this.length = length;
		}
Copy the code

Add the first test case CAR1:

		var kuahaidaqiao = new Road("Bridge across the Sea", 1000);
		var car1 = new Car("The mass"."PASSAT", 100); car1.run(kuahaidaqiao); // A PASSAT series of Volkswagen brand runs at a speed of 100km/h on a 1000km sea-crossing bridge. The final time is 10 hoursCopy the code

This is object-oriented programming, where you write the code once, and then you create the object, and you just call the wrapped function. Class and Object are two grammar of object-oriented programming, is the basis of object-oriented implementation, but there is no concept of class in JS, everything is Object, all instances are constructed by the Object constructor. So when we need a class, we create a constructor to replace the existence of a class, so the constructor is essentially a class.

Prototype mode validation method

In conjunction with the Prototype property, Javascript defines some keywords to help us use it.

  1. instanceof

    Format: object instanceof constructor

    Function: Checks whether this object is constructed by the following constructor. If so, return true; Otherwise, return false.

    alert(car1 instanceof Car); //truealert(car1 instanceof Road); //falsealert(car1 instanceof Object); //true
    Copy the code
  2. isPrototypeOf()

    Prototype. IsPrototypeOf (object)

    Function: Checks if a propToType object has an instance, and returns true if so. Otherwise, return false.

    		alert(Car.prototype.isPrototypeOf(car1)); //true
    		alert(Road.prototype.isPrototypeOf(kuahaidaqiao)); //true
    Copy the code
  3. hasOwnProperty()

    Format: object.hasownProperty (” property “)

    Function: Once created, the instance object automatically references the properties and methods of the Prototype object. That is, the properties and methods of an instance object are divided into two types, one is local and the other is referenced. Each instance object has a hasOwnProperty() method that determines whether an attribute is local or inherits from the Prototype object.

    		Car.prototype.color = "white";
    		alert(car1.hasOwnProperty("name")) / /true
    		alert(car1.hasOwnProperty("color")) / /false
    Copy the code
  4. The in operator.

    Format: “Property “in object

    Function: The IN operator can be used to determine whether an instance has an attribute, local or not.

    		alert("type" in car1); // true
    		alert("length" in car1); // false
    Copy the code

    The IN operator can also be used to iterate over all properties of an object, including methods added to it.

    for(var prop in car1) { alert("car1["+prop+"] ="+car1[prop]); } 
    Copy the code

ECMA6 syntax sugar class class

ES6 provides a simple syntactic sugar class for defining classes

The constructor is written as follows:

		function Iphone(size, color){
			this.size = size;
			this.color = color;
		}

		Iphone.prototype.show = function(){alert(' You chose one${this.color}Color, memory size is${this.size}GB mobile phone '); } var iphone1 = new Iphone(64,Rose Gold); iphone1.show(); // You have chosen a rose gold phone with 64GB of memoryCopy the code

Class:

		class Iphone{
			constructor(size, color){
				this.size = size;
				this.color = color;
			}
			show(){alert(' You chose one${this.color}Color, memory size is${this.size}GB mobile phone '); } } var iphone2 = new Iphone(256,"Black"); iphone2.show(); // You have selected a black cell phone with 256GB memoryCopy the code

inheritance

Since all instance objects share the same Prototype object, the Prototype object looks as if it is a prototype of the instance object, and the instance object looks as if it “inherits” the Prototype object. This is the idea behind Javascript inheritance.

Inheritance is object oriented, and to help you write code more efficiently, you can have one constructor inherit properties and methods from another constructor.

First we define a People class

		function Person(name, sex){
			this.name = name;
			this.sex = sex;
		}
		Person.prototype.showName = function(){
			alert("My name is" + this.name);
		}
		Person.prototype.showSex = function(){
			alert("I am" + this.sex);
		}
Copy the code

Now we are going to create a Worker class based on the Person class, with all the attributes and methods of the Person class, and add its own attribute job. We can implement inheritance through the following methods.

		function Person(name, sex){
			this.name = name;
			this.sex = sex;
		}
		Person.prototype.showName = function(){
			alert("My name is" + this.name);
		}
		Person.prototype.showSex = function(){
			alert("I am" + this.sex);
		}
Copy the code

call/apply

The first and simplest method is to bind the parent object’s constructor to the child using the Call or Apply methods. This way of inheriting Person is called constructor masquerade, because the Person object is supposed to only serve the New Person object, but it can now also be used by Worker objects.

		functionWorker(name, sex, job){// Inherit the Person attribute. Call (this, name, sex); this.job = job; } var w1 = new Worker("Xiao Ming"."Male"."Programmer");
Copy the code

The difference between Call and apply is that call(obj, PRA, pra) is followed by a single argument. Apply (obj, [args]) is followed by an array, which forces the pointer to this to change.

		functionWorker(name, sex, job){// Inherit Person attributes // constructor disguise person.apply (this, arguments); this.job = job; }Copy the code

The Person method is stored in Prototype. Prototype is an object in nature and stores reference data types, so we can’t directly assign the parent method to the child. Inheritance can only be one-way.

Each constructor has a prototype on it. We can iterate through the Prototype on Person and put the functions on Person into the Worker’s Prototype during the iterate so that they will not affect each other.

		for(var i in Person.prototype){
			Worker.prototype[i] = Person.prototype[i];
		}
Copy the code

At the same time, I expanded my method through Prototype

		Worker.prototype.showJob = function(){
			alert("I am dry." + this.job + "Working");
		}
Copy the code

Call the parent’s constructor inheritance directly

The second, more common, method uses the Prototype attribute. If the prototype object of “Worker” points to an instance of Person, then all instances of “Worker” can inherit Person.

Worker.prototype = new Person();
Copy the code

Each Prototype object has a constructor property pointing to its constructor. “Worker.prototype = new Person();” This line, the Worker. The prototype. The constructor is pointing to the Worker; After this line, the Worker. The prototype. The constructor to the Person.

alert(Worker.prototype.constructor == Person) //true
Copy the code

More importantly, each instance also has a constructor property, which by default calls the Constructor property of the Prototype object. So, run “worker.prototype = new Person();” After this line, w1.constructor also points to Person.

		var w1 = new Worker("Xiao Ming"."Male"."Programmer");
		alert(w1.constructor == Worker.prototype.constructor) //true
		alert(w1.constructor == Person.prototype.constructor) //true
		alert(w1.constructor == Person) //true
Copy the code

This obviously leads to a disorder in the inheritance chain (w1 is clearly generated using the Worker constructor), so we have to manually correct it by changing the constructor value of the worker.prototype object to Worker. This is an important point to follow when programming.

		Worker.prototype.constructor = Worker
		alert(w1.constructor == Worker.prototype.constructor) //true
		alert(w1.constructor == Person.prototype.constructor) //false
		alert(w1.constructor == Person) //false
Copy the code

Object.create() copy inheritance

The prototype object is used to implement inheritance. Alternatively, we can adopt a pure “copy” approach to inheritance. Basically, if you copy all the properties and methods of the parent object into the child object. Object.create() is similar to the concat method in arrays to create a new Object. You can copy attributes from the parent object’s Prototype object to the Child object’s Prototype object.

Worker.prototype = object.create (person.prototype); worker.prototype = object.create (person.prototype);Copy the code

polymorphism

Create a parent constructor

	function Father(name, sex, age){
		this.name = name;
		this.sex = sex;
		this.age = age;
	}
	Father.prototype.sing = function(){alert(' Father's people sing very well '); }Copy the code

Create a son constructor that inherits the attributes and methods of the parent

	functionSon(name, sex, age, degree){// Constructor's disguise Father. Call (this,name, sex, age); This. Degree = degree; } // Inheritance method // prototype chainfor(var i in Father.prototype[i]){
		Son.prototype[i] = Father.prototype[i];
	}
Copy the code

Create a son object with new and execute son1.sing() to call the method on the parent prototype.

	var son1 = new Son("Xiao Ming"."Male", 20, "Undergraduate"); son1.sing(); // My father's people sing very wellCopy the code

Now we override the parent inherited function

	Son.prototype.sing = function(){alert(' sing rock '); }Copy the code

Son1.sing () is called again, executing son1’s own added sing method.

	var son1 = new Son("Xiao Ming"."Male", 20, "Undergraduate"); son1.sing(); / sing rockCopy the code

It has no effect on the father’s own sing method, and the method overwritten at the child level only takes effect at the child level.

	var f2 = new Father("Ming"."Male", 40); f2.sing(); // My father's people sing very wellCopy the code

Now let’s look at the concepts of inheritance and polymorphism, which are actually inheritance of a part, two sides of the same thing. Inheritance focuses on inheriting properties and methods from the parent, while polymorphism focuses on properties and methods that it extends, that is, overrides. Simply put, what is the same as the parent is called inheritance, and what is different is called polymorphism.

Note: Although Son inherits the properties and methods of Father, the objects that come out of Son constructor new do not belong to Father.

	alert(son1 instanceof Son) //true
	alert(f2 instanceof Father) //true
	alert(son1 instanceof Father) //false
	alert(son1 instanceof Object) //true
Copy the code

The same case uses the ECMA6 class method to achieve inheritance and polymorphism, compared to the original method is simpler, more image.

class Father{ constructor(name, sex, age){ this.name = name; this.sex = sex; this.age = age; } // Declare methodssing(){
				alert("Can sing folk songs."); }} /* extends extends Father{constructor(name, sex, age, degree){super(name, sex, degree); age); }sing(){
				alert("Sing rock");
			}
		}

		var son1 = new Son("Xiao Ming"."Male", 30, "Undergraduate"); alert(son1.name); / / xiao Ming son1. Sing (); Var f1 = new Father("Ming"."Male", 40); alert(f1.name); / / daming f1. Sing (); // Can sing folk songsCopy the code

Prototype chain

In javascript, each object has an internal link to its prototype object. Each prototype object has its own prototype until an object’s prototype is null, forming the last link in the chain.

The constructor has a prototype property. The constructor object has a _ _proto _ _ property that points to the prototype of the constructor that constructed the object, and a name called magic variable.

That is to say, the _ _proto _ _ of son1 constructed by Son constructor is exactly equal to Son’s prototype.

alert(son1.__proto__ === Son.prototype); //truealert(f2.__proto__ === Father.prototype); //true
Copy the code

This explains why objects constructed from the same constructor use the same set of functions, because _ _proto _ _ of all objects constructed from the constructor points to the prototype of the constructor.