1. Object-oriented design 1.1 Understanding object 1.1.1 Property Type
(1). Data properties: A field that corresponds to an object that contains the position of a data value, where the value can be read and written. There are 4 attributes in the data attribute that describe their behavior:
l [[[Configurable]]: Indicates whether the property can be redefined by deleting it with delete
l [[[Enumerable]]: Indicates whether the property is returned through the for-in loop
l [[[Writable]]: Indicates whether the value of the property can be modified
l [[Value]]: Contains data values for this property
To modify the property's default attributes, you must use the ECMAScript5 Object.defineproperty () method.
(2). Accessor properties: Equivalent to an object's properties, accessor properties do not contain data values, they contain a pair of getter and setter functions, and accessor properties have the following 4 properties:
l [[[Configurable]]: Indicates whether the property can be redefined by deleting it with delete
l [[[Enumerable]]: Indicates whether the property is returned through the for-in loop
l [[Get]]: The function that is called when the property is read
l [[Set]]: The function that is called when the property is written
Accessor properties cannot be defined directly, only object.defineproperty () can be used to define
1.1.2 Defining Multiple properties
Because of the high likelihood that an object defines multiple properties, ECMASCRIPT5 defines a object.defineproperties () method that allows you to define multiple properties at once using a descriptor
1.1.3 Properties of Read attributes
Using ECMAScript5 's Object.getownpropertydescriptor () method, you can get a descriptor for a given property. If it is a data property, the property of this object has configurable,enumerable,writable and value, and if it is an accessor property, the object's properties are Configurable,enumerable,get and set;
1.2 Creating Objects 1.2.1 Factory mode
Factory mode is a well-known design pattern in the Software factory domain that abstracts the process of creating concrete objects, as shown in the following:
function Createperson (name, age, Job) { var o = new Object (); O.name = name; O.age = age; O.job = job; O.sayname = function () { alert (this.name); } return o; } var person1 = Createperson ("Chuck", "softer"); |
Factory mode solves the problem of creating multiple similar objects, but does not solve the problem of object recognition |
1.2.2 Constructor Mode
You can create custom constructors to define properties and methods for custom object types.
function person (name, age, Job) { THIS.name = name; This.age = age; This.job = job; This.sayname = function () { alert (this.name); } } var person2 = new Person ("Chuck", "tester"); Alert (Person2.constructor = = person)//true Alert (person2 instanceof person)//true |
To create a new instance of person, you must use the new operator to call the constructor in such a way that it undergoes the following 4 steps:
(1). Create a new object
(2). Assigns the scope of the constructor to the new object (so this points to the new object)
(3). Execute the code in the constructor (add properties for this new object)
(4). return new objects
The constructor property of an object is originally used to identify the object type, and the problem with constructors is that each method is implemented over each instance.
1.2.3 Prototype mode
Each function we create has a prototype (prototype) attribute, which is a pointer to an object, and the purpose of this object is to include properties and methods that can be shared by all instances of a particular type. The advantage of using a prototype object is that you can have all object instances share the properties and methods that it contains.
1.2.3.1 Understanding prototype Objects
Whenever a new function is created, a prototype property is created for the function based on a specific set of rules, which points to the prototype object of the function. By default, all prototype objects automatically get a constructor (constructor) property that contains a pointer to the function where the prototype property is located. Person.prototype.constructor points to person.
1.2.3.2 prototypes and in operators
There are two ways to use the In operator, use it separately, and for-in loop using
Used alone, the in operator returns True when the specified property is accessible by the object, regardless of whether the attribute exists in the instance or in the prototype
' Name ' in Person1
For-in, which returns all enumerable properties that can be accessed through an object, regardless of whether the attribute exists in an instance or in a prototype.
1.2.3.3 Simpler prototype syntax
For each time you add a prototype method and a property to write it over Person.prototype, it is more common to assign an object directly to the prototype object:
function person () { } Person.prototype = { Name: "Chuck", Sayname:function () { alert (this.name); } } |
There is a drawback to the appeal code, and the constructor property no longer points to person and can receive assignments to constructor
function person () { } Person.prototype = { Constructor:person, Name: "Chuck", Sayname:function () { alert (this.name); } } |
The dynamic nature of the 1.2.3.4 prototype
The lookup value in the prototype is a search, so any modifications we make to the prototype object are immediately reflected from the instance
function person () { } var friend = new person (); Person.prototype.sayname=function () { Alert ("Chuck"); } Friend.sayname (); Chuck |
However, the assignment of the overridden prototype object will cut off the connection between the existing prototype and the object instance that already exists.
function person () { } var friend = new person (); Person.prototype = { Name: "Chuck", Sayname:function () { alert (this.name); } } Friend.sayname (); Error |
1.2.3.5 prototype of native objects
The importance of prototype patterns is not only in the creation of custom types, but even in all native reference types, which are created using this pattern.
Problems with 1.2.3.6 prototype objects
The biggest drawback of prototype mode is that the properties of all prototype objects are shared by all instances, and modifying the properties of one instance affects the property values of other instances.
1.2.4 Combination Mode
The most common way to create a custom type is to combine the constructor pattern with the prototype pattern. The constructor pattern is used to define the instance type, whereas the prototype pattern is used to define methods and properties. As a result, each instance has its own copy of the instance properties, but at the same time it shares references to the object, saving the memory to a minimum. This is the most common way to create objects. For example:
function person (name, age, Job) { THIS.name = name; This.age = age; This.job = job; } Person.prototype = { Constructor:person, Sayname:function () { alert (this.name); } } var person1 = Createperson ("Chuck", "softer"); var person2 = new Person ("Chuck", "tester"); Alert (Person1.name = = person2.name)//false Alert (Person1.sayname = = person2.sayname)//true |
1.2.5 Dynamic Prototyping Mode
The dynamic prototype pattern encapsulates all the information in the constructor, while preserving the advantages of using constructors and prototypes while initializing the prototype in the constructor (only if necessary).
For example:
function person (name, age, Job) { THIS.name = name; This.age = age; This.job = job; if (typeof this.sayname! = "function") { Person.prototype.sayName = function () { alert (this.name); } } } |
1.2.6 Parasitic structural function pattern
The use of parasitic constructors is basically consistent with factory constructors, except that they are invoked in a different way. Instead of returning a value, the constructor returns a new constructor by default, and the return value of the constructor can be overridden by adding a return statement at the end of the constructor. There is no relationship between the returned object and the constructor or the stereotype property of the constructor.
function person (name, age) { var obj = new Object (); Obj.name = name; Obj.age = age; return obj; } var friend = new Person ("Chuck", 30); |
1.2.7 Secure Structural function mode
The so-called secure object refers to the absence of a public property, and its method does not refer to the This object. For example, a friend object can only be used by the Sayname method.
function person (name, age) { var obj = new Object (); Private variables and types can be defined here Add method Obj.sayname = function () { Alert (name) } return obj; } var friend = new Person ("Chuck", 30); Friend.sayname (); |
1.3 Inheriting the 1.3.1 prototype chain
The basic idea of a prototype chain is to implement inheritance by using a prototype to let one reference type inherit another property and method of the reference type.
1.3.1.1 Don't forget the default prototype
All reference objects inherit the object by default, and the inheritance is implemented through the prototype chain.
1.3.1.2 determining the relationship between prototypes and instances
There are two ways to determine the relationship between a prototype and an instance.
The first approach is to use the instanceof operator, as long as this operation characters the constructor that occurred in the test instance and the prototype chain
Alert (instance instanceof obejct); True Alert (instance instanceof supertype); True Alert (instance instanceof subtype); True |
The second way is to use the isPrototypeOf () method. Use the prototype in the prototype chain to detect if it is a prototype of the object instance
Alert (Object.prototype.isPrototypeOf (instance)); True Alert (SuperType.prototype.isPrototypeOf (instance)); True Alert (SubType.prototype.isPrototypeOf (instance)); True |
1.3.1.3 a prudent definition method
It is prudent to define the method for the prototype chain so that it does not cause code errors.
1.3.1.4 prototype chain problem
The main problem with the prototype chain is that all prototype chain methods and properties are shared, and modifications to the prototype chain properties of an instance affect the properties of other objects.
1.3.2 Borrowing constructors
In the process of solving a prototype that contains reference type values, the developer uses a technique called borrowing constructors. The basic idea of this technique is quite simple, which is to call the superclass constructor in the sub-constructor. Functions are simply objects that execute code in a particular environment, so you can use the Apply () and call () functions to execute constructors on newly created objects
function Supertype () { This.colors = ["Red", "Blue"]; } Function subtype () { Supertype.call (this); } var ins1 = new subtype (); var ins2 = new subtype (); Ins1.colors.push ("Black"); alert (ins1.colors); Red,blue,black alert (ins2.colors); Red,blur |
Borrowing constructors can pass parameters to a superclass constructor, but there is a problem with the constructor that the functions in the constructor cannot be shared and exist separately in each instance.
1.3.3 Combination Inheritance
Combinatorial inheritance refers to the combination of the prototype chain and the borrowing of the constructor, the idea of using the prototype chain to inherit the prototype method, and by borrowing the constructor to implement the inheritance of the instance properties.
function supertype (name) { this.name = name; this.colors = ["Red", "blue"]; } supertype.prototype.sayname = function () { alert (this.name); } function subtype (name, age) { Supertype.call (this,name); this.age = age; } subtype.prototype = new supertype (); subtype.prototype.constructor = subtype; subtype.prototype.sayage = function () { alert (this.age); } |
1.3.4-Prototype inheritance
The prototype allows you to create a new instance based on an existing object without having to create a custom type, creating a temporary constructor inside object, and then using the incoming object as a prototype of the constructor, and finally returning the instance object of the temporary type.
function Object (o) { function F () {}; F.prototype = O; return new F (); } |
ECMASCRIPT5 has planned the prototype inheritance by adding the Object.create () method. This method takes two parameters, an object that is used as a prototype for the new object, and (optionally) a new object that defines the extra property, and the property that is defined by the second parameter overrides the same name property on the prototype object.
1.3.5 Parasitic Inheritance
The idea of parasitic inheritance is similar to a parasitic constructor and a factory pattern, which is to create a function that encapsulates the inheritance process, which in some way enhances the object in-house.
function Object (o) { function F () {}; F.prototype = O; return new F (); } function Createanother (original) { var Clone = Object (original); Clone.sayhi = function () { Alert (' Hi '); } return clone; } |
1.3.6 Parasitic combination Inheritance
Combinatorial inheritance is the most common inheritance pattern for JavaScript, but it also has its own shortcomings. The biggest problem with combining inheritance is that in any case, two super-type constructors are called: one is when you create a sub-type prototype, the other is inside the subtype constructor, the so-called parasitic combination inheritance, that is, by borrowing the constructor to inherit the property, inheriting the method through the compositing form of the prototype chain, The basic idea behind it is that you don't have to call a super-type constructor to specify a prototype of a subtype, all we need is a copy of the super-type prototype.
function Supertype (name) { THIS.name = name; This.colors = ["Red", "Blue"]; } SuperType.prototype.sayName = function () { alert (this.name); } Function subtype (name, age) { Supertype.call (This,name); This.age = age; } Subtype.prototype = Inheritprototype (Subtype,supertype); SubType.prototype.sayAge = function () { alert (this.age); } var ins1 = new subtype (); var ins2 = new subtype (); Ins1.colors.push ("Black"); alert (ins1.colors); Red,blue,black alert (ins2.colors); Red,blur function Object (o) { function F () {}; F.prototype = O; return new F (); } function Inheritprototype (subtype,supertype) { var prototype = object (Supertype.prototype); Prototype.constructor = subtype; Subtype.prototype = prototype; } |
This approach not only invokes the Supertype constructor once, but also avoids creating unnecessary properties on the Subtype.prototype.
6. Javacript advanced Programming-Object oriented design