Speaking of object-oriented, most programmers first think of classes. Classes allow you to create many instances or objects that have common properties and methods. But JavaScript doesn't have a class concept, and almost everything in JavaScript is a problem, how do you object to JavaScript?
In JavaScript, the object is defined as a set of unordered sets of key-value pairs, the names of properties and methods, the keys, the values of which can be any type (string, number, function ...). )
In JavaScript, all objects inherit from object, all objects inherit from object, all objects inherit from object!
Create
1 Simple Object creation :
var o = new Object (); O.name = ' Mncu '; O.age = +; O.sayname = function () { alert (this.name); }; O.sayname (); ' Mncu '// literal is created with the above code equivalent var o = { name: ' Mncu ', age:120, sayname:function () { alert ( this.name); } }; O.sayname (); ' Mncu '
Although it is possible to create an object using the above method, it is also obvious that if you create an object with the same properties and methods again, you will have to copy the code again, resulting in a lot of duplicate code.
2 Factory mode
This pattern abstracts the specific process of creating an object
function Createperson (name,age) { var o = new Object (); O.name = name; O.age = age; O.sayname = function () { alert (this.name); }; return o;} var p1 = Createperson (' mncu ', +); var P2 = Createperson (' Linghuchong ', +); P1.sayname (); ' Mncu ' p2.sayname (); ' Linghuchong '
Console.log (typeof p1); Object
P1 instanceof Createperson //False, cannot determine type
But there's one drawback to this approach: you can't tell what type an object is.
3 constructor Mode
function Person (name,age) { //By convention, the first letter of the constructor should be capitalized this.name = name; This.age = age; This.sayname = function () { alert (this.name); };} var p1 = new Person (' mncu ', +); Object must be created with the new keyword var p2 = new Person (' linghuchong ', +); P1.sayname (); ' Mncu ' alert (P1 instanceof person);//True to determine type
The constructor pattern solves an issue where the object type cannot be judged in Factory mode.
When using the constructor mode, be aware that:
--You must create an object with the New keyword! The new keyword is equivalent to doing the following steps:
1 Creating a new object
2 Assign the scope of the constructor to the new object
3 code to execute the constructor
4 Returning new objects
--the object created with the constructor has a constructor property that identifies the object type, but generally we still use instanceof to determine the object type because the constructor property returns only the constructor type.
P1.constructor = = = Person //true
P1.constructor = = = Object //false
P1 instanceof Object //truep1 instanceof person//true
--the constructor is actually not much different from the normal function, because there is no special syntax, and any function, as long as it is called by new, can be used as a constructor.
var p3 = person (' Dongfangbubai ', +); When you do not use new, the scope of the function is the global scope, and this points to the Window object. P3.sayname ()// error Sayname ()// ' Dongfangbubai '
-- There are problems with constructors , and each method is created on the instance. That is to say, the Sayname () method of P1 and P2 is the same, but these two methods are not the same function.
P1.sayname = = P2.sayname //False
4 prototype Mode
The prototype pattern solves the problem that code cannot be reused for methods that are functionally related in the constructor pattern.
Each function we create has a property named prototype, which is a pointer to an object that is called a prototype object. The prototype object has a property called constructor, which is a pointer to the constructor. By default, all functions are prototyped as an instance of object.
To create an object using prototype mode:
function person () { Person.prototype.name = ' noone '; Person.prototype.age = ' noage '; Person.prototype.sayName = function () { return this.name; };} var p1 = new Person (); P1.name; ' Noone '
var p2 = new Person ()
P2.name; ' Noone '
In this example, how does the Name property of the object P1 created by the constructor show?
First P1 will find itself there is no Name property, if any, return the value of its Name property, if not, find the prototype object has no Name attribute, if the prototype object has the name attribute, then return its value, otherwise, error.
P1.name = ' Mncu ';p 1.name; ' Mncu ' p2.name; ' Noone '
We can use the hasOwnProperty () method to detect whether a property exists in a specific object or in a prototype object of that object
P1.hasownproperty (' name ') //truep2.hasownproperty (' name ')//false
We can also use the In keyword to determine whether a property exists in a specific object or in the object's prototype object.
' Name ' in P1 //True ' name ' in P2 //True
Shorthand format for prototype objects:
The function person () { } person.prototype={ //Overrides the prototype object, but the constructor of the prototype object does not point to person (object). So we will generally add: Constructor:person Constructor:person, name: ' Noone ', age : ' Noage ', sayname:function () { alert (this.name); } };
problem with prototype mode :
function person () { } person.prototype={ Constructor:person, name: ' Noone ', age : ' Noage ', [' Xiaoming '], sayname:function () { alert (this.name); } }; var p1 = new Person (); var p2 = new Person (); P1.brothers.push (' Xiaohong '); Console.log (p2.brothers)//[' xiaoming ', ' Xiaohong ']
When we change the properties of an object of a reference type, the result of that change is shared by other objects.
5 combining the constructor pattern with the prototype pattern
There is nothing wrong with the properties of the constructor pattern. The disadvantage is that methods cannot be shared
There's nothing wrong with the prototype pattern. The disadvantage is that when the value of the property of a prototype object is a reference type, modifications to it are reflected in all instances
Then we'll combine the two, the object's properties are created using the constructor pattern, and the method uses the prototype schema to create
This approach is one of the most common object-oriented programming patterns
function Person (name,age) { this.name = name; This.age = age; } person.prototype={ Constructor:person, sayname:function () { alert (this.name); } }; var p1 = new Person (' mncu ', +); P1.name; ' Mncu '
Inherited
1 prototype chain
JavaScript introduces the concept of the prototype chain, the concrete idea: the prototype object of the child constructor is initialized to an instance of the parent constructor , and the prototype object of the Sun constructor is initialized to an instance of the child constructor ..., and the object can be looked up at the first level of the prototype chain. Access properties and methods in the parent constructor.
Build a prototype chain:
function Animal (name) { this.name = name | | ' null '; This.action = [' Move ', ' wow ']; } function Cat () { this.wow = function Miao () { alert (' Miao ');} ; } function Dog () { this.wow = function () { alert (' Wang ') }; } Cat.prototype = new Animal (); Dog.prototype = new Animal (); var C1 = new Cat (); var D1 = new Dog (); Console.log (c1.action); [' Move ', ' wow '] d1.action.push (' Run '); var C2 = new Cat (); var d2 = new Dog (); Console.log (d1.action); ["Move", "wow", "Run"] Console.log (c1.action),//["move", "wow"] console.log (c2.action);//["Move", "Wow "] Console.log (d2.action); ["Move", "wow", "run"]
Problem with prototype chain inheritance:
function Superobject () { this.colors = [' Red ', ' Blue ']; } function Subobject () { } Subobject.prototype = new Superobject (); var Instance1 = new Subobject (); Instance1.colors.push (' yellow '); var instance2 = new Subobject (); Console.log (instance2.colors) //["Red", "blue", "yellow"]
When we change the properties of a prototype object that has a value of reference type, the result of this change is shared by all child objects. This disadvantage is sometimes quite deadly, so we seldom use this method to inherit
2 borrowing constructor inheritance
function Superobject () { this.colors = [' Red ', ' Blue ']; this.saybye= function () { console.log (' Bye ') } } function Subobject () { Superobject.call (this) ; The constructor of the parent class is called in the subclass, in fact the subclass and parent class already have no subordinate relationship } var instance1 = new Subobject (); Instance1.colors.push (' yellow '); var instance2 = new Subobject (); Console.log (instance2.colors); [' Red ', ' Blue '] console.log (instance2 instanceof Superobject);//False console.log (Instance1.saybye = = = Instance2.saybye) //False
This method, while compensating for the shortcomings of the prototype chain, exposes new drawbacks:
1 Subclass and Parent class have no subordinate relationship, Instance2 instanceof Superobject result is False
2 methods in the parent class are generated once in each subclass, and the methods in the parent class are not reused.
3 Combination Inheritance
Combinatorial inheritance is the combination of the inheritance of the prototype chain and the construction method inheritance, which play both lengths.
function Superobject () { this.colors = [' Red ', ' Blue ']; } superobject.prototype.saybye= function () { console.log (' Bye ') }; function Subobject () { //refers to the property of the parent type, and once called the parent function Superobject.call (this); } A method that inherits the parent type, called a parent function Subobject.prototype = new Superobject (); var Instance1 = new Subobject (); Instance1.colors.push (' yellow '); var instance2 = new Subobject (); Console.log (instance2.colors); [' Red ', ' Blue '] console.log (instance2 instanceof Superobject);//True console.log (Instance1.saybye = = = Instance2.saybye); True
4 parasitic combined inheritance----Douglas method
Although the combination of inheritance is not a big disadvantage, but love to do things with obsessive-compulsive program apes think that the combination of inheritance will call two times the parent type function (marked in the above code), not perfect. Douglas then proposed the inheritance of parasitic combinations.
The idea is to construct an intermediate function that points the prototype of the intermediate function to the prototype object of the parent function, points the prototype of the child function to the intermediate function, and points the constructor attribute of the intermediate function to the child function.
function inherits (Child, Parent) { var F = function () {}; F.prototype = Parent.prototype; Child.prototype = new F (); Child.prototype.constructor = child;} function Student (props) { this.name = Props.name | | ' Unnamed ';} Student.prototype.hello = function () { alert (' Hello, ' + this.name + '! ');} function Primarystudent (props) { Student.call (this, props); This.grade = Props.grade | | 1;} Implement the prototype inheritance chain: Inherits (Primarystudent, Student);//Bind other methods to Primarystudent prototype: PrimaryStudent.prototype.getGrade = function () { return this.grade;};
This method only calls the parent constructor once, and therefore avoids creating unnecessary, superfluous properties on the prototype object of the parent function.
Developers say: This approach is the best way to inherit (I did not see it, only think that this is the most burning of the brain of the inheritance, it seems I have a certain distance from the developer ... )
Object oriented JavaScript Advanced programming notes