Disclaimer: This article is reproduced from Nanyi blog, use please specify
JavaScript is an object-based (object-based) language, and everything is almost an object. However, it is not a real object-oriented programming (OOP) language because it has no class (class) in its syntax. If we want to encapsulate the property and method as an object, or even generate an instance object from the prototype object, there are several ways to do it:
Suppose we think of a cat as an object that has two properties of "name" and "Color".
var Cat = {
Name: ",
Color: '
}
We need to generate two instance objects based on this prototype object.
var cat1 = {}; Create an empty object
Cat1.name = "Mao";
Cat1.color = "Yellow";
var cat2 = {};
Cat2.name = "Er mao";
Cat2.color = "BLACK";
This is the simplest package, encapsulating two attributes in an object. However, there are two shortcomings in this writing, one is that if you generate several instances, it is very troublesome to write, and the other is that there is no way between the example and the prototype, and we can see what the connection is.
We can write a function that solves the problem of code duplication.
function Cat (name,color) {
return {
Name:name,
Color:color
}
}
Then generate the instance object, which is equivalent to calling the function:
var cat1 = Cat ("Da Mao", "Yellow");
var cat2 = Cat ("Er Mao", "Black");
The problem with this approach remains that there is no intrinsic connection between CAT1 and CAT2, and it does not reflect that they are instances of the same prototype object.
To solve the problem of generating instances from prototype objects, JavaScript provides a constructor (Constructor) pattern. The so-called "constructor" is actually a normal function, but the this variable is used internally. Using the new operator on a constructor enables you to generate an instance, and the this variable is bound to the instance object.
function Cat (name,color) {
This.name=name;
This.color=color;
}
var cat1 = new Cat ("Da Mao", "Yellow");
var cat2 = new Cat ("Er Mao", "Black");
alert (cat1.name); Da Mao
alert (Cat1.color); Yellow
CAT1 and Cat2 automatically contain a constructor attribute that points to their constructors.
Alert (Cat1.constructor = = Cat); True
Alert (Cat2.constructor = = Cat); True
JavaScript also provides a instanceof operator that validates the relationship between a prototype object and an instance object.
Alert (cat1 instanceof Cat); True
Alert (cat2 instanceof Cat); True
The constructor method works well, but there is a problem of wasting memory. We now add a constant property "type" for the Cat object, and then add a method eat (Eat mouse). So, the prototype object cat becomes the following:
function Cat (name,color) {
THIS.name = name;
This.color = color;
This.type = "Cat animal";
This.eat = function () {
Alert ("Eat Mouse");
};
}
The same approach is used to generate an instance:
var cat1 = new Cat ("Da Mao", "Yellow");
var cat2 = new Cat ("Er Mao", "Black");
alert (Cat1.type); Cat Animals
Cat1.eat (); Eat mice
To do so, there is a great disadvantage. That is, for each instance object, the type attribute and the Eat () method are exactly the same content. Each time an instance is generated, it must be duplicate content and occupy more memory. This is neither environmentally friendly nor inefficient.
Alert (cat1.eat = = cat2.eat); False
JavaScript specifies that each constructor has a prototype property that points to another object. All properties and methods of this object are inherited by an instance of the constructor. We can define the invariant properties and methods directly on the prototype object.
function Cat (name,color) {
THIS.name = name;
This.color = color;
}
Cat.prototype.type = "Cat animal";
Cat.prototype.eat = function () {alert ("Eat Mouse")};
Then, build the instance.
var cat1 = new Cat ("Da Mao", "Yellow");
var cat2 = new Cat ("Er Mao", "Black");
alert (Cat1.type); Cat Animals
Cat1.eat (); Eat mice
At this point the type attribute and the Eat () method for all instances are actually the same memory address, pointing to the prototype object, thus improving the efficiency of the operation.
Alert (cat1.eat = = cat2.eat); True
isPrototypeOf () This method is used to determine the relationship between a Proptotype object and an instance.
Alert (Cat.prototype.isPrototypeOf (CAT1));//true
Alert (Cat.prototype.isPrototypeOf (CAT2));//true
hasOwnProperty () is used to determine whether a property is a local property or a property inherited from a prototype object.
Alert (Cat1.hasownproperty ("name")); True
Alert (Cat1.hasownproperty ("type")); False
Now there is a constructor for an "animal" object.
function Animal () {this.species = "animal"; }
There is also a constructor for the "Cat" object.
function Cat (name,color) {this.name = name; This.color = color; }
Make "cat" Inherit "Animal"
Use the call or Apply method to bind the parent object's constructor to a child object, adding a row to the child object constructor
function Cat (name,color) {
Animal.apply (this, arguments);
THIS.name = name;
This.color = color;
}
var cat1 = new Cat ("Da Mao", "Yellow");
alert (cat1.species); Animals
If the prototype object of "cat" points to an instance of animal, then all instances of "cat" can inherit animal.
Cat.prototype = new Animal ();
Cat.prototype.constructor = Cat;
var cat1 = new Cat ("Da Mao", "Yellow"); A
Lert (cat1.species); Animals
Any prototype object has a constructor property that points to its constructor. If there is no "Cat.prototype = new Animal ();" In this line, Cat.prototype.constructor is pointing to Cat, and after adding this line, Cat.prototype.constructor points to animal. Alert (Cat.prototype.constructor = = Animal); True
More importantly, each instance also has a constructor property, which calls the prototype object's constructor property by default.
Alert (Cat1.constructor = = Cat.prototype.constructor); True
On Run "Cat.prototype = new Animal ();" After this line, Cat1.constructor also points to animal
Alert (Cat1.constructor = = Animal); True
This obviously leads to the disorder of the inheritance chain (CAT1 is obviously generated with the constructor cat), so we have to manually correct the constructor value of the Cat.prototype object to Cat
This approach is an improvement to the second method. Because of the animal object, the invariant property can be written directly to Animal.prototype. So, we can also let cat () skip Animal (), directly inherit Animal.prototype
function Animal () {}
Animal.prototype.species = "Animal";
The prototype object of the cat is then pointed to the animal prototype object, which completes the inheritance.
Cat.prototype = Animal.prototype;
Cat.prototype.constructor = Cat;
var cat1 = new Cat ("Da Mao", "Yellow"); A
Lert (cat1.species); The advantage of an animal is that it is more efficient (without having to execute and establish an instance of animal) and saves memory. The disadvantage is that Cat.prototype and Animal.prototype now point to the same object, so any modifications to Cat.prototype will be reflected in the Animal.prototype The second line actually changed the constructor attribute of the Animal.prototype object too!
alert (Animal.prototype.constructor); Cat
Since the "Direct inheritance prototype" has the disadvantages mentioned above, there is a fourth method, using an empty object as the intermediary.
var F = function () {};
F.prototype = Animal.prototype;
Cat.prototype = new F ();
Cat.prototype.constructor = Cat;
F is an empty object, so it hardly accounts for memory. At this point, modifying the cat's prototype object does not affect the animal prototype object.
alert (Animal.prototype.constructor); Animal
The above method is encapsulated into a function for ease of use.
function extend (child, Parent) {
var F = function () {};
F.prototype = Parent.prototype;
Child.prototype = new F ();
Child.prototype.constructor = child;
Child.uber = Parent.prototype;
}
When used, the method is as follows
Extend (Cat,animal);
var cat1 = new Cat ("Da Mao", "Yellow");
alert (cat1.species); Animals
This extend function, is how Yui Library implements the method of inheriting.
Simply put, all the properties and methods of the parent object are copied into the sub-object to put all the invariant properties of the animal on its prototype object.
function Animal () {}
Animal.prototype.species = "Animal";
Then, write a function that implements the purpose of the property copy.
function Extend2 (Child, Parent) {
var p = parent.prototype;
var c = Child.prototype;
for (var i in P) {
C[i] = P[i];
}
C.uber = p;
}
This function is to copy the attributes from the parent object's prototype object to the prototype object of the child object. One by one When used, write this:
Extend2 (Cat, Animal);
var cat1 = new Cat ("Da Mao", "Yellow");
alert (cat1.species); Animals
JavaScript Object-oriented