Like other object-oriented languages, JavaScript uses the reference method for object types. The variable holding the object is only an address, while the basic type data is a value. When objects are stored on the prototype, some traps may exist. By default, JavaScript uses prototype inheritance. Although there is no concept of a class, its function can act as a constructor ). The constructor can combine this, and new can build classes similar to Java. Therefore, JavaScript can simulate class-based inheritance by extending itself.
Like other object-oriented languages, JavaScript uses the reference method for object types. The variable holding the object is only an address, while the basic type data is a value. There may be some traps when the prototype stores objects.
First, let's look at the first example.
The Code is as follows:
Var create = function (){
Function Fn (){}
Return function (parent ){
Fn. prototype = parent
Return new Fn
}
}()
Var parent = {
Name: 'jack ',
Age: 30,
IsMarried: false
}
Var child = create (parent)
Console. log (child)
The create tool function implements a basic prototype inheritance. Every time you call create, a new object is copied Based on the parent object. All attributes of the new object are from the parent. Here, parent has three attributes, which are basic data types: String, number, and Boolean.
Modify the child to see if it will affect the parent.
The Code is as follows:
Child. name = 'lily'
Child. age = 20,
Child. isMarried = true
Console. log (child)
Console. log (parent)
The result is as follows:
That is, modifying child does not affect the parent.
Let's look at another example.
The Code is as follows:
Var create = function (){
Function Fn (){}
Return function (parent ){
Fn. prototype = parent
Return new Fn
}
}()
Var parent = {
Data :{
Name: 'jack ',
Age: 30,
IsMarried: false
},
Language: ['java']
}
Var child = create (parent)
Child. data. name = 'lily'
Child. data. age = 20
Child. data. isMarried = true
Child. language. push ('javascript ')
Console. dir (child)
Console. dir (parent)
Note that the two attributes data and language of the parent are reference types, including objects and arrays. Child still inherits from the parent and then modifies the child. The result is as follows:
As you can see, the parent has been modified, and is the same as the child name and age. Note This when using prototype inheritance.
When using inheritance, the better method is:
1. Data attributes are inherited by class (mounted on this), so that new data can be configured through parameters.
2. The method uses prototype inheritance, which saves memory and does not affect the parent class.
Below is a write-type tool function that satisfies the above two points
The Code is as follows:
/**
* @ Param {String} className
* @ Param {String/Function} superCls
* @ Param {Function} factory
*/
Function $ class (name, superClass, factory ){
If (superClass = '') superClass = Object
Function clazz (){
If (typeof this. init = 'function '){
This. init. apply (this, arguments)
}
}
Var p = clazz. prototype = new superCls
Clazz. prototype. constructor = clazz
Clazz. prototype. className = className
Var supr = superCls. prototype
Window [className] = clazz
Factory. call (p, supr)
}
When the object type is placed on the parent class prototype, you must be careful to modify the subclass. In this case, all instances that inherit from the parent class will be modified. The bug caused by this is not easy to find.
ES5 adds a new API to implement prototype inheritance: Object. create. You can use it to replace the self-implemented create function as follows:
The Code is as follows:
Var parent = {
Name: 'jack ',
Age: 30,
IsMarried: false
}
Var child = Object. create (parent)
Console. log (child)