1. Factory mode
The factory pattern is a creation pattern that provides the best way to create objects. We create an object inside a function, give it properties and methods, and return the object with a return
function createPerson(name, age, job) {
var o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
var person1 = createPerson('caoyuan'.25.'Software engineer')
var person2 = createPerson('neil'.23.'Software engineer')
console.log(person1) // {name: "ca ", age: 25, job: "Software engineer", sayName: ƒ}
console.log(person2) // {name: "Neil ", age: 23, job: "Software engineer", sayName: ƒ}
Copy the code
Constructor pattern
The construction pattern creates objects differently from the factory pattern;
- No object is explicitly created
- Properties and methods are assigned directly to this object
- No return object
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
this.sayName = function() {
console.log(this.name)
}
}
let person1 = new Person('caoyuan'.25.'Software Engineer')
let person2 = new Person('neil'.23.'Software engineer')
person1.sayName()
person2.sayName()
Copy the code
Calling the constructor in this way actually goes through four steps
- Create an object
- Assign the scope of the constructor to the new object (so this refers to it)
- Code that executes the constructor type (adding properties to the new object)
- Returns the object
Parasitic constructor pattern
The basic idea behind this pattern is to create a function that simply wraps the object’s code and then returns the newly created object.
function Person(name, age, job) {
var o = new Object()
o.name = name
o.age = age
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
let friend = new Person('neil'.25.'software Engineer')
friend.sayName() // neil
Copy the code
So that’s an example, throw out the new operator, and this pattern is exactly the same as the factory pattern. Constructors return a new object instance by default if they do not return a value. By adding a return statement to the end of the constructor, you can override the value returned when called to the constructor. The following example
function SpecialArray () {
// Create an array
var values = new Array(a)/ / add value
values.push.apply(values, arguments)
// Add the method
values.toPipedString = function() {
return this.join('|')}// Return the array
return values
}
var color = new SpecialArray('1'.'2'.'3')
console.log(color.toPipedString()) / / 1 | 2 | 3
Copy the code
Safe constructor pattern A safe object is an object that has no public properties and whose methods do not reference this. Suitable for use in a secure environment or to prevent data from being otherwise altered
The safe pattern follows a similar pattern to the parasitic constructor, but with two differences;
- Creating an instance of a new object does not reference this;
- The constructor is not called with the new operator
function Person(name, age, job) {
var o = new Object()
o.sayName = function() {
console.log(name)
}
return o
}
let person = Person('neil'.25.'software Engineer')
person.sayName() // neil
Copy the code
A scope-safe constructor
Introduces scope-safe constructors in codefunction Person(name, age, job) {
this.name = name
this.age = age
this.job = job
}
var person = Person('neil'.25.'Softwate Engineer')
console.log(window.age) / / 25
Copy the code
Suppose we call this to window, so the value is on window. How can we solve this problem? Modify the code as follows
function Person(name, age, job) {
if (this instanceof Person) {
this.name = name
this.age = age
this.job = job
} else {
return new Person(name, age, job)
}
}
var person = Person('neil'.25.'software Engineer')
console.log(window.age) // undefined
console.log(person.age) / / 25
Copy the code
Now it seems that there is no problem in determining whether this is currently on the Person instance by using instanceof, so suppose that the inheritance of the pattern is stolen by using the constructor and the prototype chain is not used, the inheritance might be broken
function Polygon(sides) {
if (this instanceof Polygon) {
this.sides = sides
this.getArea = function() {
return 0}}else {
return new Polygon(sides)
}
}
function Rectangle(width, heigth) {
Polygon.call(this.2)
this.width = width
this.heigth = heigth
this.getArea = function () {
return this.width * this.heigth
}
}
let rect = new Rectangle(5.10)
console.log(rect.sides) // undefined
Copy the code
Rect. Sides is undefined. The Polygon instance is safe, but the Rectangle inherits Polygon’s sides attribute via call. So we create a new Polygon object. Rectangle does not have sides attribute. If constructor stealing is used in combination with prototype chains and parasitic patterns, the code is as follows
function Polygon(sides) {
if (this instanceof Polygon) {
this.sides = sides
this.getArea = function() {
return 0}}else {
return new Polygon(sides)
}
}
function Rectangle(width, heigth) {
Polygon.call(this.2)
this.width = width
this.heigth = heigth
this.getArea = function () {
return this.width * this.heigth
}
}
Rectangle.prototype = new Polygon()
let rect = new Rectangle(5.10)
console.log(rect.sides) / / 2
Copy the code
Three, prototype mode
Each function we create has the Prototype property, which is a pointer to an object that contains properties and methods that can be shared by all the columns of a particular type. A prototype object is an instance object created by calling the constructor.
function Person() {
}
Person.prototype.name = 'caoyuan'
Person.prototype.age = '25'
Person.prototype.sayName = function() {
console.log(this.name)
}
let person1 = new Person()
let person2 = new Person()
person2.sayName()
person1.sayName()
console.log(person1.sayName == person2.sayName)
Copy the code
Dynamic prototype mode
It wraps all the information in the constructor, and retains the advantage of using both the constructor and the stereotype by initializing the stereotype in the constructor
function Person(name, age, job) {
this.name = name
this.age = age
this.job = job
/ / method
if (typeof this.sayName ! ='function') {
Person.prototype.sayName = function() {
console.log(this.name)
}
}
}
let person = new Person('neil'.25.'Software Engineer')
person.sayName()
Copy the code
Use a combination of constructor and prototype patterns
The most common way to create custom objects is to use a combination of the constructor and prototype patterns.
- The constructor pattern defines the properties of an instance
- The stereotype pattern is used to define methods and shared properties
function Person(name, age, job) {
this.name = name
this.age = age
this.children = ['1'.'2']
}
Person.prototype.sayName = function() {
console.log(this.name)
}
let person1 = new Person('caoyuan'.25.'Software Engineer')
let person2 = new Person('neil'.23.'Software Engineer')
person1.children.push('3')
console.log(person1.children) / / Array [1, 2, 3]
console.log(person2.children) / / Array [1, 2]
console.log(person1.children === person2.children) // false
console.log(person1.sayName === person2.sayName) // true
Copy the code