CHAP6: Object-Oriented Programming
Object-oriented (Object-oriented,oo) languages have a sign that they all have the concept of a class, and that a class can create any number of objects that have the same properties and methods. As mentioned earlier, there is no concept of class in ECMAScript, so its objects are also different from objects in class-based languages.
ECMA-262 defines an object as: "A collection of unordered attributes whose properties can contain basic values, objects, or functions." "Strictly speaking, this is equivalent to saying that the object is a set of values that do not have a particular order. Each property or method of an object has a name, and each name is mapped to a value. Because of this (and other reasons to be discussed), we can think of the ECMAScript object as a hash table: nothing more than a set of name-value pairs where the value can be data or function.
6.1 Understanding Objects
As explained in the previous chapter, the simplest way to create a custom object is to create an instance of an object and then add properties and methods to it, as shown below.
1 var person = new Object (); 2 person.name = "Nicholas" 3 person.age = 29; 4 person.job = "Software Engineer" ; 5 person.sayname = () { 6 alert (this .name); 7 };
The above example creates an object named person and adds three attributes (name, age, and job) and a method (Sayname ()) to it. where the Sayname () method is used to display the value of this.name (which will be resolved to Person.name). Early JavaScript developers often use this pattern to create new objects. A few years later, object literals became the preferred mode for creating such objects. The preceding example can be written like this with the object literal syntax:
1 var person = {2 name: "Nicholas",3 age:29,4 job: "Software Engineer",5 function () {6 alert (this. Name); 7 }8 };
The person object in this example is the same as the person object in the previous example, and has the same properties and methods. These properties are created with some characteristic values (characteristic), which JavaScript uses to define their behavior.
6.2 Creating objects
6.2.1 Factory mode
Factory mode is a well-known design pattern in the field of software engineering that abstracts the process of creating concrete objects (other design patterns and their implementation in JavaScript are discussed later in this book). Considering the inability to create a class in ECMAScript, the developer invented a function that encapsulates the details of creating an object with a specific interface, as shown in the following example.
1 functionCreateperson (name, age, job) {2 varn \NewObject ();3O.name =name;4O.age =Age ;5O.job =job;6O.sayname =function(){7Alert This. Name);8 };9 returno;Ten } One varPerson1 = Createperson ("Nicholas", "Software Engineer"); A varPerson2 = Createperson ("Greg", "Doctor");
The function Createperson () is able to construct a person object that contains all the necessary information based on the parameters that are accepted. This function can be called countless times, and each time it returns an object that contains a method of three attributes. Factory mode solves the problem of creating multiple similar objects, but does not solve the problem of object recognition (that is, how to know the type of an object). With the development of JavaScript, another new paradigm has emerged.
6.2.2 Constructor Mode
As explained in the previous chapters, constructors in ECMAScript can be used to create objects of a specific type. Native constructors, such as Object and Array, will automatically appear in the execution environment at run time. In addition, you can create custom constructors that define properties and methods for custom object types. For example, you can use the constructor pattern to rewrite the preceding example as follows.
1 functionPerson (name, age, job) {2 This. Name =name;3 This. Age =Age ;4 This. Job =job;5 This. Sayname =function(){6Alert This. Name);7 };8 }9 varPerson1 =NewPerson ("Nicholas", "Software Engineer");Ten varPerson2 =NewPerson ("Greg", "Doctor");
In this example, the person () function replaces the Createperson () function. We note that the code in person () has the following differences in addition to the same parts in Createperson ():
(1) There is no explicit creation of an object;
(2) Assigning attributes and methods directly to the This object;
(3) No return statement.
It should also be noted that the function name person uses the uppercase letter P. As a rule, constructors should always start with an uppercase letter, while non-constructors should start with a lowercase letter. This approach is borrowed from other OO languages, primarily to distinguish it from other functions in ECMAScript, because the constructors themselves are functions, but can be used to create objects.
To create a new instance of person, you must use the new operator. Calling a constructor in this way actually goes through 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) Executing the code in the constructor (adding attributes to the new object);
(4) Returns the new object.
At the end of the previous example, Person1 and Person2 each hold a different instance of person. Both objects have a constructor (constructor) property that points to person, as shown below.
1 // true 2 // true
The constructor property of an object is originally used to identify the object type. However, it is more reliable to refer to the detection object type or the instanceof operator. All of the objects we create in this example are both instances of object and instances of person, which can be verified by the instanceof operator.
1 instanceof // true 2 instanceof // true 3 instanceof // true 4 instanceof // true
Creating a custom constructor means that its instance can be identified as a specific type in the future, which is where the constructor pattern is better than the factory pattern. In this example, Person1 and Person2 are both instances of object because all objects are inherited from object (details are discussed later).
6.2.4 combination using constructor mode and prototype 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 instance properties, and the prototype schema is used to define methods and shared properties. As a result, each instance will have its own copy of the instance properties, but at the same time it shares a reference to the method, saving the memory to a minimum. In addition, this blending pattern also supports passing parameters to the constructor, which is the length of the two modes. The following code overrides the previous example.
1 functionPerson (name, age, job) {2 This. Name =name;3 This. Age =Age ;4 This. Job =job;5 This. Friends = ["Shelby", "Court"];6 }7Person.prototype = {8 Constructor:person,9Sayname:function(){TenAlert This. Name); One } A } - varPerson1 =NewPerson ("Nicholas", "Software Engineer"); - varPerson2 =NewPerson ("Greg", "Doctor"); thePerson1.friends.push ("Van"); -alert (person1.friends);//"Shelby,count,van" -alert (person2.friends);//"Shelby,count" -Alert (person1.friends = = = Person2.friends);//false +Alert (Person1.sayname = = = Person2.sayname);//true
In this example, the instance properties are defined in the constructor, and the properties constructor and Method Sayname () shared by all instances are defined in the prototype. modifying Person1.friends (Adding a new string to it) does not affect person2.friends, because they refer to different arrays respectively. This pattern of constructors and prototypes is the most widely used and most recognized method of creating custom types in ECMAScript. It can be said that this is a default pattern for defining reference types.
JS Object-Oriented programming notes