An in depth understanding of the JavaScript series (47) : object creation patterns (part 1)
- 2020-05-10 17:45:16
- OfStack
introduce
This article focuses on patterns for creating objects, using techniques that can greatly avoid errors or allow you to write very lean code.
Pattern 1: namespace (namespace)
Namespaces can reduce the number of global names needed to avoid naming conflicts or excesses. 1. When we define object hierarchy, it is usually like this:
var app = app || {};
app.moduleA = app.moduleA || {};
app.moduleA.subModule = app.moduleA.subModule || {};
app.moduleA.subModule.MethodA = function () {
console.log("print A");
};
app.moduleA.subModule.MethodB = function () {
console.log("print B");
};
If you have a lot of layers, you have to keep going like this. It's very confusing. namespace mode is designed to solve this problem. Let's look at the code:
// It is not safe and may overwrite the existing one MYAPP object
var MYAPP = {};
// ok
if (typeof MYAPP === "undefined") {
var MYAPP = {};
}
// A more concise way
var MYAPP = MYAPP || {};
// Defining generic methods
MYAPP.namespace = function (ns_string) {
var parts = ns_string.split('.'),
parent = MYAPP,
i;
// Default if no 1 A node is MYAPP If so, ignore it, for example MYAPP.ModuleA
if (parts[0] === "MYAPP") {
parts = parts.slice(1);
}
for (i = 0; i < parts.length; i += 1) {
// If the property does not exist, it is created
if (typeof parent[parts[i]] === "undefined") {
parent[parts[i]] = {};
}
parent = parent[parts[i]];
}
return parent;
};
The calling code is very simple:
// through namespace Later, you can assign the return value to 1 Local variables
var module2 = MYAPP.namespace('MYAPP.modules.module2');
console.log(module2 === MYAPP.modules.module2); // true
// skip MYAPP
MYAPP.namespace('modules.module51');
// Very long name
MYAPP.namespace('once.upon.a.time.there.was.this.long.nested.property');
Pattern 2: define dependencies
Sometimes one of your modules or functions may refer to a third module or tool. It is best to define the dependencies at the beginning so that they can be easily replaced later.
var myFunction = function () {
// Rely on the module
var event = YAHOO.util.Event,
dom = YAHOO.util.dom;
// Local variables are used in the code that follows other functions event and dom
};
Pattern 3: private properties and private methods
The JavaScript book does not provide a specific syntax to support private properties and private methods, but we can do this with closures, as follows:
function Gadget() {
// Private objects
var name = 'iPod';
// The public function
this.getName = function () {
return name;
};
}
var toy = new Gadget();
// name Undefined, private
console.log(toy.name); // undefined
// Public method access name
console.log(toy.getName()); // "iPod"
var myobj; // Give through the self-executing function myobj The assignment
(function () {
// Free object
var name = "my, oh my";
// It implements the public part, so it doesn't var
myobj = {
// Authorization method
getName: function () {
return name;
}
};
} ());
Mode 4: Revelation mode
It is also about hiding private methods, similar to the Module pattern in the JavaScript series (3) : fully parsing the Module pattern, but instead of declaring a variable externally and assigning it a public method internally. The code is as follows:
var myarray;
(function () {
var astr = "[object Array]",
toString = Object.prototype.toString;
function isArray(a) {
return toString.call(a) === astr;
}
function indexOf(haystack, needle) {
var i = 0,
max = haystack.length;
for (; i < max; i += 1) {
if (haystack[i] === needle) {
return i;
}
}
return -1;
}
// All the above details are hidden by assignment
myarray = {
isArray: isArray,
indexOf: indexOf,
inArray: indexOf
};
} ());
// The test code
console.log(myarray.isArray([1, 2])); // true
console.log(myarray.isArray({ 0: 1 })); // false
console.log(myarray.indexOf(["a", "b", "z"], "z")); // 2
console.log(myarray.inArray(["a", "b", "z"], "z")); // 2
myarray.indexOf = null;
console.log(myarray.inArray(["a", "b", "z"], "z")); // 2
Pattern 5: chain pattern
Chain mode allows you to call methods of one object in a row, such as obj.add (1).remove (2).delete (4).add (2). The idea is very simple, which is to return this as it is. The code is as follows:
var obj = {
value: 1,
increment: function () {
this.value += 1;
return this;
},
add: function (v) {
this.value += v;
return this;
},
shout: function () {
console.log(this.value);
}
};
// Chain method call
obj.increment().add(3).shout(); // 5
// You can do it alone 1 a 1 A call
obj.increment();
obj.add(3);
obj.shout();
conclusion
This is the first part of the object creation pattern, so stay tuned for the next part tomorrow.