brief introduction
Six concepts of object-oriented: object (instance), class, encapsulation, inheritance, polymorphism and aggregation.
js does not have the concept of class. It extends new objects based on objects (constructors and prototype objects).
Encapsulation: put the independent attributes in the constructor and the shared part on the prototype. Save memory and keep the instance object independent.
Constructor: the constructor is the same as ordinary functions. The difference is that it gets an object by executing new, and returns this by default, which points to the newly created object.
Create an object through the constructor:
function Person (name) { this.name = name; } Person.prototype.sayName = function () { alert(this.name) } var p1 = new Person('Tom', 10); //p1:'Tom',10;__proto__: sayName
The following relationships exist:
p1.__proto__ === Person.prototype // true Person.prototype.constructor === Person //true p1.constructor === Person.prototype.constructor //true
Three important attributes
_proto_
Object unique. Point to the prototype of the corresponding constructor, that is, the prototype attribute.
Function: when accessing the properties of an object, the object itself (private property) will be searched. If not, it will be searched in its_ proto_ The prototype object pointed to by the property cannot be found until object Protoytpe object, which returns undefined before it is. (prototype chain lookup)
The prototype chain is simply through_ proto_ A chain that connects objects to null.
p1----->Person.prototype----->Object.prototype----->null
Everything in js is an Object and can be based on_ proto_ Prototype chain found Object Protoytpe prototypes are all instances (objects) of the built-in class Object.
prototype
Function unique. Refers to the prototype object of the function.
Role: contains attributes and methods shared by instances (public attributes or methods).
Object.prototype.__proto__ === null // true
constructor
Object unique. Refers to the constructor of the object. The default built-in property in the prototype object points to the constructor itself.
Built in (class) object constructor
Number / String / Boolean / Object/ Array / Date / Funtion / RegExp / Error
console.log(Person.__proto__ === Function.prototype);//true console.log(Number.__proto__ === Function.prototype);//true console.log(String.__proto__ === Function.prototype);//true console.log(Boolean.__proto__ === Function.prototype);//true console.log(Date.__proto__ === Function.prototype);//true console.log(Array.__proto__ === Function.prototype);//true console.log(Error.__proto__ === Function.prototype);//true console.log(RegExp.__proto__ === Function.prototype);//true
Detection example
p1 instanceof Person // true Person.prototype.isPrototypeOf(p1) // true p1.hasOwnProperty('name') // true p1.hasOwnProperty('sayName') // false
Instance instanceof class
Check whether the instance belongs to a class. As long as the prototype of the class appears on the prototype chain of the instance object, it returns true. It is applicable to array or regular, but not to basic data types
isPrototypeOf
Detect the relationship between a proptype object and an instance
Object Hasownproperty
Check whether a property is the private property of the instance object. If it is not the property of the object or the private property, false will be returned
Attribute in object
Regardless of public or private attributes, as long as it is the attribute of the object, it returns true
attr in obj && ! attr. Hasownproperty (attr) is a property of an object and is not private
inherit
Construction inheritance: execute the constructor of the parent class in the constructor of the child class and point to its own this
function Parent(name){ this.name = name } Parent.prototype.getName = function(){ return this.name } function Child (){ Parent.call(this,'hello') } var child = new Child() console.log(child.name) // hello console.log(child.getName()) // child.getName is not a function
Disadvantages:
Methods and properties on the parent class prototype cannot be inherited. Only properties and methods of the parent class instance can be inherited.
Prototype inheritance: take the instance of the parent class as the prototype of the child class
function Parent(){ this.name = 'hello' this.hobbies = ['walking','music'] } Parent.prototype.getName = function(){ return this.name } function Child (){ } // Let child prototype. Constructor points to Parent Child.prototype = new Parent() Child.prototype.constructor = Child var child1 = new Child() var child2 = new Child() console.log(child1.name) // hello console.log(child1.getName()) // hello child2.hobbies[0] = 'baseketball' console.log(child2.hobbies) // ["baseketball", "music"] console.log(child1.hobbies) // ["baseketball", "music"]
Disadvantages: multiple instances point to the same prototype. Modifying one of them will affect others (including reference type values); You cannot pass parameters to a parent class.
Composite inheritance: a combination of prototype inheritance and construction inheritance
function Parent(name){ this.name = name this.hobbies = ['walking', 'music'] } Parent.prototype.getName = function(){ return this.name } function Child (name){ Parent.call(this, name) } // Let child prototype. Constructor points to Parent Child.prototype = new Parent() Child.prototype.constructor = Child var child1 = new Child('hello') var child2 = new Child() console.log(child1.name) // hello console.log(child1.getName()) // hello child2.hobbies[0] = 'baseketball' console.log(child2.hobbies) // ["baseketball", "music"] console.log(child1.hobbies) // ["walking", "music"]
Parasitic composite inheritance: it avoids the defect of instantiating the parent class every time in composite inheritance
function Parent(name){ this.name = name this.hobbies = ['walking', 'music'] } Parent.prototype.getName = function(){ return this.name } function Child (name){ Parent.call(this, name) } // Change new Parent to parent prototype // Child.prototype = Parent.prototype // Shallow copy Child.prototype = Object.create(Parent.prototype) Child.prototype.constructor = Child var child1 = new Child('hello') var child2 = new Child() console.log(child1.name) // hello console.log(child1.getName()) // hello child2.hobbies[0] = 'baseketball' console.log(child2.hobbies) // ["baseketball", "music"] console.log(child1.hobbies) // ["walking", "music"]
Disadvantages: when changing the prototype prototype, we should pay attention to the interaction between the prototype objects of the subclass and the parent class, which can be avoided by shallow copy
ES6 class inheritance
It is implemented directly through extensions, and super is used to call the constructor of the parent class in the subclass. The definition of class includes the constructor constructor and the function getName() defined on the prototype object.
class Parent{ constructor(name){ this.name = name } getName() { return this.name } } class child extends Parent{ constructor(name){ super(name) //Call the constructor of the parent class with super } } var child1 = new Parent('hello') console.log(child1.name) // hello
Add