A trap inherited by JavaScript prototypes
JavaScript defaults to prototype inheritance. Although there is no concept of class, its functions (function) can act as constructors (constructor). Constructors with This,new can build Java-like classes. Thus, JavaScript can emulate Class (class-based) inheritance by extending itself.
JavaScript, like other object-oriented languages, uses the object type as a reference. The variable holding the object is just an address, and the base type data is the value. When you store objects on a prototype, there may be some pitfalls.
Let's look at the first example.
var create = function () { function Fn () {} return function (parent) {Fn.prototype = parent return new Fn}} () var parent = {name: ' Jack ' 30false " var child = Create (parent) console.log (child)
The Create tool function implements a basic prototype inheritance, where each call to create copies a new object based on the parent object, and all properties of the new object are derived from the parent. Here the parent has three attributes, all of which are basic data types: String, Number, Boolean.
Then modify the child to see if it will affect the parent
Child.name = ' Lily '=true console.log (Child) Console.log (parent)
The results are as follows
That is, modifying a child does not affect the parent.
And look at another example.
varCreate =function() { functionFn () {}return function(parent) {Fn.prototype=Parentreturn NewFn}} () varParent ={data: {name:' Jack ', Age:30, ismarried:false}, language: [' Java ']}varChild =Create (parent) Child.data.name= ' Lily 'Child.data.age= 20child.data.isMarried=trueChild.language.push (' JavaScript ') Console.dir (Child) Console.dir (parent)
Note that the two properties of the parent in this data,language are reference types, one is an object and the other is an array. Child still inherits with the parent, then modifies the child, the result is as follows
As you can see, the parent is also modified, and the child's name,age and so on are the same. This is what you need to be aware of when using prototype inheritance.
The better way to use inheritance is to:
1, the data attributes are class-inherited (hang on this), so new can also be configured by the parameters
2, the method uses the prototype inheritance, this can save memory, and the subclass overriding method does not affect the parent class
The following is a write-class tool function that satisfies the above 2 points
/** * @param {String} className * @param {string/function} supercls * @param {Function} factory*/function$class (name, superclass, factory) {if(Superclass = = = ") Superclass =ObjectfunctionClazz () {if(typeof This. init = = ' function ') { This. init.apply ( This, arguments)} } varp = Clazz.prototype =Newsupercls Clazz.prototype.constructor=Clazz Clazz.prototype.className=ClassNamevarSUPR =Supercls.prototype Window[classname]=clazz Factory.call (P, SUPR)}
When the object type is placed on the parent class prototype, be careful that the subclass modifies it, and instances of all subclasses that inherit from the parent class are modified. The resulting bug is not easy to find.
A new API was added to the ES5 to implement the prototype inheritance: Object.create. You can use it instead of the above self-implemented create function, as follows
var parent = { ' Jack ', +, false}var Child = Object.create (parent) console.log (child)
A trap inherited by JavaScript prototypes