By Jeskson Source: front end tavern of dada
1
In learning JavaScript, we know that it is a flexible language, with object-oriented, functional style programming mode, object-oriented has two points to remember, three features, six principles.
So what are they? What are the three specific characteristics? Keep in mind three major features: Encapsulation, Inheritance, and Polymorphism. We often talk about three characteristics: Encapsulation, Inheritance, Polymorphism. Six principles are: single responsibility principle (SRP), open and closed principle (OCP), Richter's replacement principle (LSP), dependency inversion principle (DIP), interface separation principle (ISP), least knowledge principle (LKP).
Knowledge of inheritance:
Inheritance, if there are many classes, the properties or methods in each class are different, and some properties or methods are the same, so if you define them, sometimes you need to define these same properties or methods repeatedly.
This leads to code duplication, which leads to the emergence of inheritance. Inheritance is that the son inherits the gene of Laozi. Let a class "son class" inherit their "father", so that all the "father" can have the same attributes or methods. Such a class is called "parent class". Inheritance, as its name implies, means that a son inherits Laozi and has Laozi's properties or methods. By this way, all the subclasses can access these properties or methods, instead of defining them in the subclass every time. It's more convenient, faster, faster and more efficient!
In fact, JavaScript is not a strong object-oriented language, because its flexibility determines that not all object-oriented features are suitable for JavaScript development.
We actually talked about classes. How do we understand classes?
What is a class? A class is a collection of properties or methods that can be used to create an instance object through its constructor. In other words, if we regard human beings as a class, and each of us is an instance object, the instance object of a class includes two aspects:
All non static (properties or methods) of a class All static (properties or methods) of a class
Non static (attribute or method) is unique to each instance and belongs to personality. All static (attributes or methods) are the commonness of each instance and belong to commonness.
In other words, personality (non static) means that everyone's name is different, and the attribute of name is non static; commonness (static) means that everyone has to eat, and eating is a static method.
2
So how are classes implemented in JavaScript?
Class implementation:
Using function to create class, using new keyword to generate instance object; using constructor to realize non-static (property or method), using prototype to realize static (property or method).
// Create function function dashucoding() { console.log('dashucoding') } // Assignment of functions var da = dashucoding() // undefined // Instance object var jeskson = new dashucoding() // {}
Among them, dashucoding is a common function and a class constructor. When dashucoding() is called, it will be executed as a common function, and dashucoding will be output. Because there is no return value, it will return undefined; when new dashucoding() is called, dashucoding will be output and an object will be returned.
We use the function dashucoding to construct objects, so we think of this dashucoding as a constructor. Construction object, constructor. That is, by using functions and defining constructors, it is equivalent to defining a class and generating an instance object through the new keyword.
// Constructor function dashucoding(name) { this.name = name } var da1 = new dashucoding('jeskson'); var da2 = new dashucoding('jeckson'); console.log(da1.name) // jeskson console.log(da2.name) // jeckson
Among them, there are multiple parameters in dashucoding constructor and this.name=name in function body. This in this sentence points to the instantiated object returned by new keyword.
According to the different parameters in the constructor, the generated object has different attribute name values. What is the name here? Can you see that? It is the non static (property or method) of this class.
So how to use prototype to achieve static? (knowledge points of prototype chain)
3
Prototype object chain, prototype chain and JavaScript built-in inheritance methods are called prototype object chain, also known as prototype object inheritance. There is a saying that for an object, because it inherits the properties of its prototype object, it can access these properties, and the prototype object is also an object. Similarly, it can also have its own prototype object, so it can also inherit the properties of its prototype object.
What? I don't know if I didn't understand it. I think it's like Xiaobai and the ghost can understand it. Prototype inherits chain concept, object inherits its prototype object, while prototype object inherits its prototype object. That's a concept you can understand, what? What? What? Reward you with a big mouth, your mother will increase the price of food, super double. Your grandfather must point when he plays chess.
Prototype chain? What is the prototype of the class? What is the proto of the object?
prototype in class
Called prototype: in JavaScript, whenever we define a constructor, a prototype is automatically added to the class in the JavaScript engine.
In JavaScript, when we use new to create an object, the JavaScript engine will automatically add a "proto" attribute to the object and point to its class's prototype.
// Constructor function dashucoding(name) { // Non static properties this.name = name; } // Whenever we define a constructor, the JavaScript engine will automatically // Add a prototype to the class console.log(dashucoding.prototype) var da1 = new dashucoding('jeskson'); var da2 = new dashucoding('jeckson'); // proto of object console.log(da1.__proto__); console.log(da2.__proto__); console.log(dashucoding.prototype === da1.__proto__); // true console.log(dashucoding.prototype === da2.__proto__); // true
Among them, dashucoding.prototype is an object, and the instantiated object da1 and da2 of dashucoding class all have an attribute, proto, which is also an object. And dashucoding. Prototype is equal to the ﹐ proto ﹐ of da1 or da2.
The equality of reference types in JavaScript means that they all point to the same object, and the proto property of any instantiated object points to the prototype of its class.
Property in object:
// Object Assignment var pro = { name: 'jeskson'; } var person = { __proto__: pro } console.log(person.name) // jeskson person.name = 'jeckson' console.log(person.name) // jeckson
See, the person does not define the name attribute, and the result of console.log is jeskson. Why? This is the prototype chain result of the most powerful JavaScript.
In fact, when we go back to the code, we know that there is an associated relationship. The value of the property "proto" in person is pro, and the pro points to the Object "pro". The property in Pro has the name:'jeskson', and there are also the property "proto" with the value of Object, while the Object points to the Object, and the property of the Object also has the property "proto" with the value of null.
Come on, let's talk about the situation more clearly. When we visit person.name, what is the process like?
When we access person.name, we can see that we didn't write the property name. First, person.name will find whether there is a name property in the object. If not, it will find the property object "proto". Do you see that there is this property in person, let alone not?
No, you just didn't read the article carefully. No, you just didn't read the content. No, you just didn't fit in.
The value of "proto" property object in person is a pro object, so "proto" of person points to the object of "pro", then it will be found that there is a property of "name" in the object of "pro", then it can return the value of "jessson".
But if we add the name attribute to person, first see whether we add the name value to the code. At this time, the person.name value in console.log will not look for the "proto" attribute. We will first look for the name attribute. The value is "Jackson", so print the returned "Jackson".
Here we focus on one thing: pro's proto point is Object, and each Object has the proto attribute, which points to the created objects. They are objects of the Object class by default, so remember that the Object's attribute, proto, points to Object.prototype naturally.
OK, then read the prototype chain. For what is not mentioned above, use prototype to implement static (property or method).
// Using prototype to implement static (property or method) // Constructor function dashucoding(name) { this.name = name; } // Using prototype to implement static (property or method) // Method created dashucoding.prototype.eat = function() { console.log('i eat'); } // Instance object var da1 = new dashucoding('jeskson'); var da2 = new dashucoding('jeckson'); // Add a method to this person da1.eat() // i eat da2.eat() // i eat console.log(da1.eat === da2.eat) // true
One of them is: dashucoding.prototype.eat = function() {...}. All the instantiated objects (proto) through dashucoding point to dashucoding.prototype.
As long as there is no non-static (property or method) with the same name defined in the constructor, each object accesses the eat method found inside it, so we use the prototype chain to implement the static (property or method) of the class.
// Constructor function dashucoding(name) { this.name = name; eat() { console.log('i eat'); } } // This is the same name
4
Object inheritance. When creating an object by using the literal value of the object, it implicitly points to [[Prototype]] of the new object. When creating an object by using the Object.create() method, it will display [[Prototype]] of the specified new object. The Object.create() method takes two parameters, the first is the [[Prototype]] of the new object, and the second describes the properties of the new object.
It's silly again!!!
// Object literal form var da = { name: 'jeskson' } // The prototype is implicitly set in the form of Object.prototype, so you can understand // Object.create(), indicating that Object.prototype is specified var dada = Object.create(Object.prototype, { dashucoding: { id: '123', code: 'dashucoding', value: 'Front end' } })
Please remember the above code and keep it in mind.
Implement object inheritance:
var da = { // attribute name: 'jeskson', // Method write: function() { console.log(this.name); } } var dada = Object.create(da, { name: {value: 'jeckson' } }) da.write(); // 'jeskson' dada.write(); // 'jeckson'
console.log(da.hasOwnProperty('write')); // true console.log(da.isPrototypeOf(dada)) // true console.log(dada.hasOwnProperty('write') // false console.log('write' in dada); // true console.log(dada.__proto__ === da); // true console.log(dada.__proto__ === Object.prototype) // true
Prototype chain inheritance:
Prototype chain is the main method for JavaScript to implement inheritance. Its basic idea is to use prototype to let one reference type inherit the properties and methods of another reference type. The basic pattern for implementing a prototype chain is to make the prototype object of the current constructor equal to the instance of another constructor.
function A(name, age) { this.name = name; this.age = age; this.family = ["Dad","Mom"]; if(typeof(this.getName) != "function") { A.prototype.getName = function() { return this.name; } } } function B() { this.job = 'IT'; if(typeof(this.getJob) != "function") { B.prototype.getJob = function() { return this.job; } } } B.prototype = new A("jeskson", 12); var da = new B(); // The attribute name and age of instance da are inherited from prototype B. Prototype console.log(da.name); // jeskson console.log(da.age); // 12 console.log(da.hasOwnProperty("name")); // false console.log(da.hasOwnProperty("age")); // false
// The prototype B.prototype of instance da is rewritten, so the constructor of da points to A console.log(da.constructor == B); console.log(da.constructor == A); // Output false, true
// A complete prototype chain // da.__proto__ > B.prototype.__proto__ > A.prototype.__proto__ > Object.prototype console.log(B.prototype.isPrototype(da)); // true cosole.log(A.prototype.isPrototype(B.prototype)); // true console.log(Object.protoype.isProtypeOf(A.prototype)); // true
Prototype chain inheritance: Object inheritance in JavaScript is the basis of constructors. Almost all functions have prototype properties. Except for the function constructed by Function.prototype.bind method, it can be replaced and modified.
The prototype chain implements inheritance, allowing the subclass to inherit the static state (property or method) of the parent class
// Parent class function Father() {} Father.prototype.say = function() { console.log('father') } function Son() {} var son1 = new Son(); console.log(son1.say); // undefined // Key code of prototype chain implementation inheritance Son.prototype = new Father(); var son2 = new Son(); console.log(son2.say) // function(){...}
When we use Son.prototype = new family(), all objects generated through new Sow() will have a "proto" attribute, which points to Son.prototype. It implements that the child class inherits the static state (property or method) of the parent class.
Prototypes and prototype chains in JavaScript:
Prototype: every function we create has a prototype property, which is a pointer to an object. The purpose of this object is to share properties and methods with all instances of a specific type. The advantage of using a prototype is that all object instances can share the properties and methods contained in the prototype object.
function da(){} da.prototype.name = 'jeskson'; da.prototype.age = 12; da.prototype.job = 'it'; da.prototype.sayName = function() { alert(this.name); } var person1 = new da(); person1.sayName(); // jeskson var person2 = new da(); person2.sayName(); // jeskson alert(person1.sayName() === person2.sayName()); // true
Da.prototype points to the prototype object, da.prototype.constructor points to Da, and a new function is created by default. Its prototype object only contains the constructor property, and the internal property of the instance of Da object only points to da.prototype
5
__Proto, all objects have a proto property, an implicit prototype, pointing to the prototype object that constructs the constructor of the object.
function da() {} da.prototype.name = 'jeskson'; da.prototype.age = 12; da.prototype.job = 'it'; da.prototype.sayName = function() { alert(this.name); } // Instanced object var person1 = new da(); console.log(da); // da(){} console.log(da.prototype); console.log(da.prototype.__proto__); console.log(da.prototype.constructor); console.log(person1); console.log(person1.__proto__);
Prototype chain: when an attribute is added to an object instance, the attribute will mask the object with the same name in the prototype object.
function da() {} da.prototype.name = 'jeskson'; da.prototype.age = 12; da.prototype.job = 'it'; da.prototype.sayName=function() { alert(this.name); } var person1 = new da(); console.log(person1.name); // jeskon person1.name="jeckson" console.log(person1.name); // jeckson person1.name = null console.log(person1.name); // null delete person1.name // Delete, instance properties, pay attention to instance properties console.log(person1.name); // jeskson
The constructor has a prototype property, which points to the prototype object of the instance object. The prototype object has a constructor property, which points to the constructor corresponding to the prototype object. The instance object has a proto property, which points to the prototype object corresponding to the instance object.
Prototype method:
isPrototypeOf() method is used to judge the relationship between a prototype object and an instance:
alert(Cat.prototype.isPrototypeOf(cat1)); //true alert(Cat.prototype.isPrototypeOf(cat2)); //true
hasOwnProperty() method, each instance object has a hasOwnProperty() method, which is used to determine whether a property is a local property or inherits the property of the prototype object.
alert(cat1.hasOwnProperty("name")); // true alert(cat1.hasOwnProperty("type")); // false
in operator, used to determine whether an instance contains a property, whether it is a local property or not.
alert("name" in cat1); // true alert("type" in cat1); // true
Constructor, prototype, relationship between instances:
Constructor is a common way to create objects. Other ways to create objects include factory mode, prototype mode, object literal, etc. Let's look at a simple constructor.
// Constructor function Da(name, age) { // The naming convention for constructors uses uppercase for the first letter this.name = name; this.age = age; }
Every constructor has a prototype property. The Da.prototype property is actually a pointer to an object. The object has a constructor property, so the prototype property in the constructor points to an object.
Archetype:
Whenever a new function is created, a prototype property will be created for the function according to a specific set of rules. This property points to the prototype object of the function. By default, all prototype objects will automatically get a constructor() construction function. This property contains a pointer to the function where the prototype property is located.
The face is muddled!!!
Relationship between constructor and prototype
There is a prototype attribute in the constructor, which points to the constructor in the prototype object, and the constructor() constructor in the prototype object, which points to the pointer in the constructor.
Prototype: the object pointed to by the prototype property of the constructor. (prototype object)
In the prototype object, there is a constructor property that refers back to the constructor itself.
function Da(name,age) { this.name = name; this.age = age; } var da = new Da('jeskson', '12');
The process of creating objects through constructors is called instantiation, and the created objects are called instances
Add a method for the prototype:
Da.prototype.eat = function() { console.log('i eat'); }
Invoke the method in an instance:
var da = new Da('jeskson', '12'); da.eat(); // i eat
Properties and methods in the prototype can be used on instances connected to their corresponding constructors.
Relationship between constructor, instance and prototype
What's in the constructor?
prototype in constructor
What's in the prototype?
The prototype has constructor, eat() method
What's in the example?
Instance has properties or methods
Best example code:
// Create Da1 constructor function Da1 () { this.name = 'jeskson'; } // Add a method to the prototype of the Da1 constructor Da1.prototype.eat1 = function() { console.log('i eat da1'); } // Create Da2 constructor function Da2 () { this.name = 'jeckson'; } // Assign instance object of Da1 directly to prototype of D2 Da2.prototype = new Da1(); // Add a method to the prototype of Da2 Da2.prototype.eat2 = function() { console.log('i eat da2'); } // Instantiation of Da2 var da2 = new Da2(); da2.eat1(); // jeskson
6
Prototype chain inheritance. When function declaration creates a function, the prototype property of the function is automatically set as an object inherited from Object.prototype. The object has its own property constructor, whose value is the function itself.
// Constructor function Da() {} // JavaScript engine Da.prototype = Object.create(Object.prototype, { constructor: { name: true, age: true } }); console.log(Da.prototype.__proto__ === Object.prototype); // true
The constructors created are all inherited from Object.prototype. JavaScript Engine helps you set the prototype property of the constructor to an object inherited from Object.prototype.
Constructor implements inheritance, allowing the subclass to inherit the nonstatic (property or method) of the parent class
// Constructor function Da(name) { this.name = name } function Son() { Da.apply(this, agruments) this.sing = function() { console.log(this.name); } } var obj1 = new Son('jeskson'); var obj2 = new Son('jeckson'); obj1.sing(); // jeskson obj2.sing(); // jeckson
The combination mode implements inheritance, prototype chain inheritance and constructor foundation, and implements the static and non-static (property or method) inheritance of the parent class.
function Father(name) { this.name = name } Father.prototype.sayName = function() { console.log(this.name); } function Son() { Father.apply(this, arguments) } Son.prototype = new Father(); var son1 = new Son('jeskson'); var son2 = new Son('jeckson'); son1.sayName(); // jeskson son2.sayName(); // jeckson
The parasitic combination method implements inheritance: Super function, let the prototype of Father parasitize on the prototype of Super, let Son inherit Super, and then put the process into a closure.
// Constructor function Father(name) { this.name = name } Father.prototype.sayName = function() { console.log(this.name); } function Son() { Father.apply(this,arguments) } (function() { function Super(){} Super.prototype = Father.prototype Son.prototype = new Super() }()) var son1 = new Son('jeskson');
Inner call of subtype constructor parent constructor
function getArea() { return this.length * this.width } /* Quadrilateral */ function Rectangle(length, width) { this.length = length this.width = width } /* Acquisition area */ Rectangle.prototype.getArea = getArea /* Get dimension information */ Rectangle.prototype.getSize = function() { console.log(`Rectangle: ${ this.length }x${ this.width },The measure of area: ${ this.getArea() }`) } /* Square */ function Square(size) { Rectangle.call(this, size, size) this.getArea = getArea this.getSize = function() { console.log(`Square: ${ this.length }x${ this.width },The measure of area: ${ this.getArea() }`) } } var rect = new Rectangle(5, 10) var squa = new Square(6) rect.getSize() // Rectangle: 5x10, area: 50 squa.getSize() // Square: 6x6, area: 36
7
Object oriented, creating objects, creating with constructors
var obj = new Object();
Literal creation:
var obj = {};
Factory mode:
var p1 = new Object(); p1.name = 'da'; p1.age = '12' p1.showName = function() { return this.name } var p2 = new Object(); p2.name = 'da2'; p2.age = '23', p2.showName = function() { return this.name }
Adopt factory mode, abstract the process of creating objects, encapsulate the same properties or methods
function createF(name, age) { var obj = new Object(); obj.name = name; obj.age = age; obj.showName = function() { return this.name; }; return obj; } var p1 = createF('jeskson',12); var p2 = createF('jeckson',23);
Construction mode:
function Person(name, age) { this.name = name; this.age = age; this.showName = function() { console.log(this.name); } } var p1 = new Person('Zhang San', '1'); var p2 = new Person('Li Si', '2');
What is a prototype chain:
In JavaScript, the main method of inheritance is through the prototype chain, which means that one prototype object is equal to an instance of another type. Because the instance contains a pointer to the constructor, it is equivalent to rewriting the prototype object. At this time, the prototype object contains a pointer to another prototype. The bottom layer of the prototype chain is: object. Prototype. \\\\\\\\\.
There is only one structure in JavaScript that is an object. Each instance object has a private property called "proto" which points to its constructor's prototype object. The prototype object also has its own prototype object, proto object, which goes up layer by layer until the prototype object of an object is null.
Based on the inheritance of prototype chain, JavaScript objects have a chain pointing to a prototype Object, and the Object.prototype property represents the prototype Object of the Object.
let f = function() { this.a = 1; this.b = 2; } // function f() { this.a = 1; this.b = 2; } // let o = new f(); // {a:1,b:2} f.prototype.b=3; f.prototype.c=4;
When the inherited function is called, this refers to the current inherited object, rather than the prototype object of the inherited function.
var o = { a: 2, m: function() { return this.a+1; } }; console.log(o.m()); // 3 //When o.m is called, 'this' points to o var p = Object.create(o); // p is an object inherited from o p.a = 4; console.log(p.m());
function doSomething(){} doSomething.prototype.foo = "bar"; console.log( doSomething.prototype );
Use Object.create to create an object
var a = {a: 1}; // a ---> Object.prototype ---> null var b = Object.create(a); // b ---> a ---> Object.prototype ---> null console.log(b.a); // 1 (inherited) var c = Object.create(b); // c ---> b ---> a ---> Object.prototype ---> null var d = Object.create(null); // d ---> null console.log(d.hasOwnProperty); // undefined, because d does not inherit Object.prototype
About the content of the current article that involves the front-end, PHP knowledge points, if you are interested in it, you can pay attention to it. It's a great honor to be found by you. It's really smart to know English! Thank you for your attention. In the future, I hope to support me silently all the time, and I will try to write more excellent works. We grow up together, from zero basic programming, to present the Web front-end field, data structure and algorithm, network principle and other easy to understand to small partners. Share technical articles, tool resources, selected courses and hot information related to Web front-end.
Feedback: If the content of this number is not in place (for example, involving copyright or other issues), please contact us in time for rectification, and we will deal with it as soon as possible.
Thanks for reading. It's not easy to be original. Just like it. It's my biggest motivation for writing.
Welcome to your attention. Dada The short book!
This is a blog with quality and attitude