This paper discusses the JS implementation of prototype pattern, then discusses the relationship between JavaScript prototype inheritance and prototype pattern.
Prototype pattern is a form of creation, and its intent in the Gof book is described as specifying the type of object to be created with a prototype instance, and creating new objects by copying the prototypes.
Prototype pattern itself is actually very simple, any object that provides a clone () method can be a prototype object, and all objects copied through it belong to a class of objects. In a static language, this pattern is used to specify object types at run time, and is much more convenient to implement than Factory mode, which eliminates the need to create a factory class structure that is parallel to the class hierarchy.
Three kinds of JS implementations of clone
In JS, the Clone method implementation is not difficult, for JS 6 basic types, string Boolean undefined null number can be directly used = assign value, the only trouble is object.
The function that we can copy as a method with all the members of a clone can be defined in this way:
/************************************/
function objectClone ()
{
var ret=new Object();
for(var p in this)
{
ret[p]=this[p];
}
return ret;
}
But we obviously face a problem: this[p] may also be an object so it's possible that we need to use the recursive return to implement Deepclone
function objectDeepClone()
{
var ret=new Object();
for(var p in this)
{
if (typeof ret[p]!=object)ret[p]=this[p];
else ret[p] =objectDeepClone.call(this[p]);
}
return ret;
}
For JS, there is another way to implement clone, in JavaScript, the constructor's prototype attribute indicates a class of prototypes, when instantiated, this prototype is used as the object's prototype. In particular, this prototype object may have been constructed from a prototype, which forms a structure similar to inheritance, so JavaScript's prototype-oriented features are also called prototype inheritance (although I disagree with this practice, I'd like to mention it).
Back in front of us Prototype Pattern,javascript's innate reference-type prototype inheritance gives us another way to implement the clone:
function objectPrototypeClone()
{
var tmp=function(){};
tmp.prototype=this;
return new tmp;
}
So that the cloned object only shares the attributes of a stereotype, its greatest advantage is that it is very fast, and when we want to quickly replicate large objects, we can use this approach, but it will result in slower access, and it reflects the changes in the parent node in real time.
Clones of built-in objects
But, by the way, we haven't considered the built-in objects, and the built-in objects can't be clone with normal method. We have a few built-in objects to consider:
Function Array String Boolean number Date
REGEXP error and math do not need to clone the scene so it is not in our consideration.
It is impossible for a function to completely produce a copy, because we cannot guarantee that the constructed function is in the same scope as the original function, but it is easy to do not include the implementation of the scope:
eval (this);
or use function constructs
Return Function (The new String ("return") +this) ();
The Function itself is an object, so you must add the clone implementation of object Functionprototypeclone need a little gimmick.
/************************************/
function functionClone()
{
var ret=Function(new String("return ")+this)();
for(var p in this)
{
ret[p]=this[p];
}
return ret }/************************************/
function functionDeepClone()
{
var ret=Function(new String("return ")+this)()
for(var p in this)
{
if(typeof ret[p]!=object)ret[p]=this[p];
ret[p]=objectDeepClone.call(this[p]);
}
return ret }/************************************/
function functionPrototypeClone()
{
var tmp=Function.prototype Function.prototype=this var ret=(new Function(new String("return ")+this))();
Function.prototype=tmp return ret }
/************************************/