1. Prototype Pattern
Using existing objects as prototypes, get new objects through clone (to simplify the creation process of new objects)
(From [Ayqy: Design Patterns Summary ("Head First Design Patterns" Learning Summary)](/articles/设计模式总结(《head-first 设计模式》学习总结)/))
Very similar to inheritance, enhancing the prototype pattern further becomes inheritance. Prototype pattern only cares about attribute copying, while inheritance besides implementing attribute copying also needs to ensure parent/child type hierarchy relationships
2. Specific Implementation
1. Basic Principle
// Beget function
function beget(obj) {
var F = function() {};
F.prototype = obj;
return new F();
}
// test
var obj = {
attr: 1,
fun: function() {
console.log(this.attr);
}
}
var cp_obj = beget(obj);
cp_obj.fun(); // 1
Core is the beget function, puts the passed object into empty constructor's prototype, creates object and returns, that's all
One obvious disadvantage: attributes from prototype object (in this case obj) may be accidentally overwritten
P.S. Prototype object obj can be an object created in any way, in this case is object literal, of course can also be new'ed, can be beget'ed, etc.
2. Simple Enhancement
ES5 supports Object.create function to get shallow copied objects, can directly replace beget with:
Object.create(obj);
Result is exactly the same, because Object.create internal implementation is inspired by Douglas's prototype pattern, additionally Object.create can have a second parameter, used to define attributes:
Object.create(obj, {
attr: {
value: 2,
writable: false, // default value
configurable: false, // default value
enumerable: true
}
});
Actually combines Object.create and Object.defineProperty together, for example:
// test
var obj = {
attr: 1,
fun: function() {
console.log(this.attr);
}
}
var cp_obj = Object.create(obj, {
attr2: {
value: 2,
writable: false, // default value
configurable: false, // default value
enumerable: true
}
});
cp_obj.fun(); // 1
console.log(cp_obj.attr2); // 2
cp_obj.attr2 = 3;
console.log(cp_obj.attr2); // 2, not writable
Of course, Object.defineProperty is also only supported from ES5, so using together counts as an enhancement (access control)
3. Benefits of Prototype Pattern
There's a nice sentence in the book:
One of the benefits of using the Prototype pattern is that we gain the prototype advantages that JavaScript itself possesses, rather than trying to imitate characteristics of other languages.
Prototype pattern implemented in Java looks very strange, because for the prototype pattern itself, Java's Object.clone can already satisfy the needs, any other form of implementation seems redundant, while JavaScript initially didn't provide clone native implementation (ES5's Object.create makes up for this defect), so needs prototype pattern, after ES5 goes into production no longer needs to manually implement any prototype pattern
For more introduction about prototype pattern please check 23 Design Patterns (5): Prototype Pattern
Reference Materials
-
"JavaScript Design Patterns"
No comments yet. Be the first to share your thoughts.