When you create objects from the object constructor or object literal, a large number of duplicate code is generated when you create many objects using the same interface. In order to simplify, the factory model was introduced.
Factory mode
function Createperson (name, age, Job) {
var obj = new Object ();
Obj.name = name;
Obj.age = age;
Obj.job = job;
Obj.sayhello () {
alert (this.name);
};
return obj;
}
var P1 = Createperson ("Xxyh", "programmer");
var P2 = Createperson ("Zhangsan", "student");
This way of creating objects greatly simplifies the code, but there is also a lack of certainty about the type of object. To solve this problem, the following pattern appears.
Constructor pattern
Create a custom constructor that defines the properties and methods of the custom object type.
function person (name, age, Job) {
this.name = name;
This.age = age;
This.job = job;
This.sayname = function () {
alert (this.name);}
;
} var p1 = new Person ("Xxyh", "programmer");
var p2 = new Person ("Jack", "student");
In the example above, the person () replaces Createperson (), and there are several differences:
• Create objects without displaying them;
• Assign properties and methods directly to the This object
• No return statement
To create a person object, you must use the new operator. is divided into 4 steps:
• Create a new object
• Assign a constructor's scope to a new object
• Execute the code in the constructor
• Return new Object
P1 and P2 each hold an instance of person.
Alert (P1.constructor = = person); True
alert (p2.constructor = = person); True
It is best to use instanceof when detecting types:
Alert (P1 instanceof Object); True
alert (P1 instanceof person); True
alert (P2 instanceof Object); True
alert (P2 instanceof person); True
Both P1 and P2 are instances of object because all objects inherit from object.
2.1 Constructor as a function
Use the Var person as a constructor
= new Person ("Xxyh", "programmer");
Person.sayname (); "Xxyh"
//as ordinary function person
("Zhangsan", "student"); Add to Window
window.sayname (); ' Zhangsan '
//calling
var obj = new Object ()
in the scope of another. Person.call (obj, "Jack", "Manager");
Obj.sayname (); "Jack", obj has all the properties and methods
2.2 Problems with constructors
The problem with constructors is that each method is recreated on each instance. Both P1 and P2 have a sayname () method, but they are not instances of a function. In JavaScript, a function is an object, so each definition of a function instantiates an object.
Constructors can also be defined like this:
function person (name, age, Job) {
this.name = name;
This.age = age;
This.job = job;
This.sayname = new Function ("Alert (this.name)");
}
Therefore, the functions of the same name on different instances are not equal:
Alert (P1.sayname = = p2.sayname); False
However, creating two functions with the same functionality is redundant and does not require that the function be bound to a particular object before the code is executed.
function person (name, age, Job) {
this.name = name;
This.age = age;
This.job = job;
This.sayname = Sayname;
}
function Sayname () {
alert (this.name);
}
var p1 = new Person ("Xxyh", "programmer");
var p2 = new Person ("Jack", "student");
This moves the definition of sayname () to the outside of the constructor, and then sets the property sayname to the global sayname function inside the constructor. In this way, Sayname contains pointers to functions, p1 and P2 share the same sayname () function defined in the global scope.
However, there is a new problem with this: a function defined in a global scope can only be invoked by an object. And if the object defines many methods, the reference type loses its encapsulation.
Prototype chain mode
Each function has a prototype (prototype) attribute, which is a pointer to an object. The purpose of this object is to include properties and methods that can be shared by all instances of a particular type . Prototype is the prototype object of that object instance that was created by calling the constructor. The advantage of using a prototype object is that all object instances can share the properties and methods it contains. This means that you do not have to define the information for an object instance in the constructor, but instead add that information to the prototype object.
function person () {
}
Person.prototype.name = "Xxyh";
Person.prototype.age =;
Person.prototype.job = "Programmer";
Person.prototype.sayName = function () {
alert (this.name);
};
var person1 = new Person ();
Person1.sayname (); "Xxyh"
var person2 = new Person ();
Person2.sayname (); "Xxyh"
alert (person1.sayname = = person2.sayname);//True
3.1 Understanding the Prototype object
As soon as a new function is created, a prototype property is created for the function, which points to the prototype object of the function. By default, all prototype objects will automatically get a constructor property. This property contains a pointer to the function where the prototype property resides. Person.prototype.constructor point to Person.
When a constructor is called to create an instance, an instance's interior will contain a pointer to the constructor's prototype object (internal property), called [[Prototype]]. Accessed via _proto_ in Firefox, Safari and Chrome. This connection exists between the instance and the stereotype object of the constructor, not between the instance and the constructor.
The following illustration shows the relationships between objects:
The Person.prototype points to the prototype object, and the Person.prototype.constructor refers back to the person. In addition to the constructor attribute in the prototype, there are other added properties. The person instance contains an internal property that points only to Person.prototype, which is not directly related to the constructor.
Although [[Prototype]] cannot be accessed, the isPrototypeOf () method can be used to determine whether the relationship exists between objects.
Alert (Person.prototype.isPrototypeOf (Person1)); True
alert (Person.prototype.isPrototypeOf (Person2)); True
When you read an object's properties, a search is performed, and the target is a property with the given name. The search starts first from the object instance itself. The search begins with the object instance itself, if a property with the given name is found in the instance, returns the value of the property, or, if not found, continues to search the prototype object that the pointer points to, looking for the property of the given name in the prototype object. If this property is found in the prototype object, the value of the property is returned.
You can access values that are stored in the prototype through an object instance, but you cannot override the values in the prototype through an object instance . If you add a property in the instance with the same name as a property in the instance prototype, the property will mask the properties in the prototype.
function person () {
}
Person.prototype.name = "Xxyh";
Person.prototype.age = "a";
Person.prototype.job = "Programmer";
Person.prototype.sayName = function () {
alert (this.name);
};
var person1 = new Person ();
var person2 = new Person ();
Person1.name = "Oooo";
alert (person1.name); "Oooo"
alert (person2.name); "Xxyh"
In the example above, the Name property in Person1 masks the name attribute in the prototype.
When an object instance adds a property, this property masks the property of the same name that is saved in the prototype object. This means that the existence of this property prevents access to that attribute in the prototype. Use Delete to complete the Delete instance property.
function person () {
}
Person.prototype.name = "Xxyh";
Person.prototype.age = "a";
Person.prototype.job = "Programmer";
Person.prototype.sayName = function () {
alert (this.name);
};
var person1 = new Person ();
var person2 = new Person ();
Person1.name = "Oooo";
alert (person1.name); "Oooo"
alert (person2.name); "Xxyh"
delete person1.name;
alert (person1.name); "Xxyh"
hasOwnProperty () can detect whether an attribute exists in the instance or in the prototype.
function person () {
}
Person.prototype.name = "Xxyh";
Person.prototype.age = "a";
Person.prototype.job = "Programmer";
Person.prototype.sayName = function () {
alert (this.name);
};
var person1 = new Person ();
var person2 = new Person ();
Alert (Person1.hasownproperty ("name")); False
Person1.name = "Oooo";
Alert (Person1.hasownproperty ("name")); True
The following diagram shows the relationship between implementations of different situations and prototypes:
3.2 Prototypes with in operators
Using the IN operator: used separately, in the for-in loop. When used alone, the in operator returns True when the given property is accessible through an object, whether the property exists in the instance or in the prototype.
function person () {
}
Person.prototype.name = "Xxyh";
Person.prototype.age = "a";
Person.prototype.job = "Programmer";
Person.prototype.sayName = function () {
alert (this.name);
};
var person1 = new Person ();
Alert ("name" in Person1); True
person1.name = "Oooo";
Alert ("name" in Person1); True
Combined with the previous hasownproperty () feature, you can determine whether an attribute is a property in the prototype or an attribute in the instance. If the In operator returns True and hasOwnProperty returns False, the property is a property in the prototype.
function Hasprototypeproperty (object, name) {return
!object.hasownproperty (name) && (name in object);
}
Next, look at the use of Hasprototypeproperty ():
function person () {
}
Person.prototype.name = "Xxyh";
Person.prototype.age = "a";
Person.prototype.job = "Programmer";
Person.prototype.sayName = function () {
alert (this.name);
};
var person = new person ();
Alert (Hasprototypeproperty (person, "name")); True
person.name = "Oooo";
Alert (Hasprototypeproperty (person, "name")); False
When you use the for-in loop, you return all enumerable properties that can be accessed through the object, including the properties in the instance and the properties in the stereotype. The instance property of the block that is not enumerated in the prototype (that is, [[[Enumerable]] marked as false) is also returned in for-in because the attributes defined by the developer are enumerable.
To get all the enumerable instance properties on an object, you can use the Object.keys () method.
function person () {
}
Person.prototype.name = "Xxyh";
Person.prototype.age = "a";
Person.prototype.job = "Programmer";
Person.prototype.sayName = function () {
alert (this.name);
};
var keys = Object.keys (Person.prototype);
alert (keys); Name, age, Job, Sayname
var p1 = new Person ();
P1.name = "Oooo";
P1.age =;
var P1_keys = Object.keys (p1);
alert (P1_keys); Name, age
If you need to get all instance properties, you can use the Object.getownpropertynames () method
var keys = object.getownpropertynames (Person.prototype);
alert (keys); "Constructor,name,age,job,sayname"
3.3 Simpler prototype syntax
To streamline input, rewrite the consolidated prototype object with an object literal that contains all the properties and methods.
function person () {
}
person.prototype = {
name: "Xxyh",
age:18,
job: "Programmer",
sayname: function () {
alert (this.name);
}
};
The above sets the person.prototype to be equal to a new object created in the literal form of an object. The result is the same, but the constructor property is not pointing to person.
The correct result can be returned through instanceof, but constructor cannot determine the type of the object:
var boy = new Person ();
Alert (boy instanceof Object); True
alert (boy instanceof person); True
alert (boy.constructor = = person); False
alert (boy.constructor = = Object); True
You can set constructor values in the following ways:
function person () {
}
person.prototype = {
Constructor:person,
name: "Xxyh",
age:18,
Job: "Programmer",
sayname:function () {
alert (this.name);
}
;
3.4 Dynamics of the prototype chain
Since the process of locating a value in a prototype is a search, any modifications made to the prototype object are reflected on the instance. But if you rewrite the entire prototype object, the result is different. Calling a constructor adds a [[prototype]] pointer to the original prototype for the instance, and modifying the stereotype to another object is tantamount to cutting off the constructor's connection to the original prototype. the pointer in the instance points only to the stereotype, not to the constructor.
function person () {
}
var boy = new Person ();
Person.prototype = {
Constructor:person,
name: "Xxyh",
age:29,
job: "Programmer",
Sayname:func tion () {
alert (this.name);
}
};
Boy.sayname (); Error
The specific process is as follows:
As you can see from the above, rewriting the prototype object cuts off the connection between the existing prototype and any previously existing object instances, which refer to the original prototype.
3.5 prototype of native objects
All native reference types define a method on the stereotype of a constructor. The prototype of the native object allows you to not only get the default method, but also define a new method.
String.prototype.startsWith = function (text) {return
this.indexof (text) = 0;
};
var msg = "Good Morning";
Alert (Msg.startswith ("good")); True
3.6 Problems with prototype objects
There are two problems with the prototype pattern:
• The same property values are obtained by default.
• All attributes in the prototype are shared by the instance
Let's look at an example:
function person () {
}
person.prototype = {
Constructor:person,
name: "Xxyh",
age:18,
job: " Programmer ",
friends:[" John "," Dick "],
sayname:function () {
alert (this.name);
}
;
var p1 = new Person ();
var p2 = new Person ();
P1.friends.push ("Harry");
alert (p1.friends); John, Dick, Harry
alert (p2.friends); John, Dick, Harry
alert (p1.friends = = p2.friends); True
The above is added by P1.friends, because the friends array exists in Person.prototype, so it is reflected in p2.friends. However, the example is generally to have their own all the attributes.
Combining constructor patterns with prototype patterns
Constructor patterns are used to define instance properties, which are used to define methods and shared properties. In this way, each instance has a copy of its own instance attribute, but it also shares a reference to the method.
function person (name, age, Job) {
this.name = name;
This.age = age;
This.job = job;
This.friends = ["John", "Dick"];
}
Person.prototype = {
Constructor:person,
sayname:function () {
alert (this.name);
}
}
var p1 = new Person ("The Rustle of the cold", "programmer");
var p2 = new Person ("Quebec pull", 10, "Catch Demon");
P1.friends.push ("Harry");
alert (p1.friends); John, Dick, Harry
alert (p2.friends); John, Dick
alert (p1.friends = = p2.friends); False
alert (p1.sayname = = p2.sayname); True
In the example above, the instance property is defined in the constructor, and the shared property constructor and Method Sayname () are defined in the prototype. The p1.friends modification does not affect the results of the p2.friends.
Dynamic Prototyping Mode
The dynamic prototyping pattern encapsulates all the information in the constructor, and by initializing the prototype in the constructor, it retains the advantage of using both constructors and prototypes. This means that you can decide whether to initialize a prototype by checking whether a method that should exist is valid.
function person (name, age, Job) {
//attribute
this.name = name;
This.age = age;
This.job = job;
Method
if (typeof this.sayname!= "function") {
Person.prototype.sayName = function () {
alert (this.name);
}
}
}
This is only added to the prototype when the Sayname () method does not exist, and will only be executed when the constructor is first invoked.
Parasitic constructor patterns
The idea of this pattern is to create a function that encapsulates the code that creates the object and then returns the newly created object.
function person (name, age) {
var obj = new Object ();
Obj.name = name;
Obj.age = age;
Obj.sayname = function () {
alert (this.name);
}
return obj;
}
var boy = new Person ("Xxyh", "programmer");
Boy.sayname ();
Note: First, there is no relationship between the returned object and the constructor or the stereotype property of the constructor; The constructor returns an object that is not different from the object created outside the constructor. You cannot rely on the instanceof operator to determine the object type.
Secure constructor Mode
A secure object is an object that has no public properties and whose methods do not refer to this. A secure constructor follows a pattern similar to a parasitic constructor, but there are two different points:
• The instance method of the newly created object does not refer to this;
• Call constructors without using the new operator
Rewrite the person constructor as follows:
function person (name, age, Job) {
var obj = new Object ();
Obj.sayname = function () {
alert (name);
};
return obj;
}
function person (name, age, Job) {
var obj = new Object ();
Obj.sayname = function () {
alert (name);
};
return obj;
}
The above article on the creation of JavaScript object is a small series to share all the content of everyone, hope to give you a reference, but also hope that we support the cloud-dwelling community.