All Constructor Instances Have Constructor Properties That Point to Their Constructor Function
When any object is instantiated, the
constructor
property is created behind the scenes as a property of that object or instance. This property points to the constructor function that created the object. In the next code sample, we create an Object()
object, stored in the foo
variable, and then verify that the constructor
property is available for the object we created.
Sample: sample23.html
1
2
3
4
5
6
7
8
| <!DOCTYPE html><html lang= "en" ><body><script> var foo = {}; console.log(foo.constructor === Object) // Logs true, because object() constructed foo. console.log(foo.constructor) // Points to the Object() constructor function. </script></body></html> |
This can be useful: If Im working with some instance and I cant see who or what created it (especially if it is someone elses code), I can determine if its an array, an object, or whatever.
In the following sample, you can see that I have instantiated most of the pre-configured objects that come included with the JavaScript language. Note that using literal or primitive values does not mean that the
constructor
pointer is not resolved when the primitive literal value is treated as an object.
Sample: sample24.html
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| <!DOCTYPE html><html lang= "en" ><body><script> var myNumber = new Number( '23' ); var myNumberL = 23; // Literal shorthand. var myString = new String( 'male' ); var myStringL = 'male' ; // Literal shorthand. var myBoolean = new Boolean( 'true' ); var myBooleanL = true ; // Literal shorthand. var myObject = new Object(); var myObjectL = {}; // Literal shorthand. var myArray = new Array(); var myArrayL = []; // Literal shorthand. var myFunction = new Function(); var myFunctionL = function () { }; // Literal shorthand. var myDate = new Date(); var myRegExp = new RegExp( '/./' ); var myRegExpL = /./; // Literal shorthand. var myError = new Error(); console.log( // All of these return true. myNumber.constructor === Number, myNumberL.constructor === Number, myString.constructor === String, myStringL.constructor === String, myBoolean.constructor === Boolean, myBooleanL.constructor === Boolean, myObject.constructor === Object, myObjectL.constructor === Object, myArray.constructor === Array, myArrayL.constructor === Array, myFunction.constructor === Function, myFunctionL.constructor === Function, myDate.constructor === Date, myRegExp.constructor === RegExp, myRegExpL.constructor === RegExp, myError.constructor === Error ); </script></body></html> |
The
constructor
property also works on user-defined constructor functions. In the following sample, we define a CustomConstructor()
constructor function, then using the keyword new
, we invoke the function to produce an object. Once we have our object, we can then leverage the constructor
property.
Sample: sample25.html
01
02
03
04
05
06
07
08
09
10
11
12
13
| <!DOCTYPE html><html lang= "en" ><body><script> var CustomConstructor = function CustomConstructor() { return 'Wow!' ; }; var instanceOfCustomObject = new CustomConstructor(); // Logs true. console.log(instanceOfCustomObject.constructor === CustomConstructor); // Returns a reference to CustomConstructor() function. // Returns 'function() { return 'Wow!'; };' console.log(instanceOfCustomObject.constructor); </script></body></html> |
You might be confused as to why primitive values have constructor properties that point to constructor functions when objects are not returned. By using a primitive value, the constructor is still called, so there is still a relationship with primitive values and constructor functions. However, the end result is a primitive value.
If you would like the
constructor
property to log the actual name of the constructor for user-defined constructor functions, you have to give the constructor function an actual name (e.g., var Person = function Person(){};
).Verify That an Object Is an Instance of a Particular Constructor Function
By using the
instanceof
operator, we can determine (true or false) if an object is an instance of a particular constructor function.
In the next sample, we are verifying if the object
InstanceOfCustomObject
is an instance of the CustomConstructor
constructor function. This works with user-defined objects as well as native objects created with the new
operator.
Sample: sample26.html
01
02
03
04
05
06
07
08
09
10
11
12
13
14
| <!DOCTYPE html><html lang= "en" ><body><script> // User-defined object constructor. var CustomConstructor = function () { this .foo = 'bar' ; }; // Instantiate an instance of CustomConstructor. var instanceOfCustomObject = new CustomConstructor(); console.log(instanceOfCustomObject instanceof CustomConstructor); // Logs true. // Works the same as a native object. console.log( new Array( 'foo' ) instanceof Array) // Logs true. </script></body></html> |
One thing to watch out for when dealing with the
instanceof
operator is that it will return true
any time you ask if an object is an instance of Object
, since all objects inherit from the Object()
constructor.
The
instanceof
operator will return false when dealing with primitive values that leverage object wrappers (e.g., 'foo' instanceof String // returns false
). Had the string 'foo'
been created with the new
operator, the instanceof
operator would have returned true. So, keep in mind that instanceof
really only works with complex objects and instances created from constructor functions that return objects.An Instance Created From a Constructor Can Have Its Own Independent Properties (Aka Instance Properties)
In JavaScript, objects can be augmented at any time (i.e. dynamic properties). As previously mentioned, and to be exact, JavaScript has mutable objects. This means that objects created from a constructor function can be augmented with properties.
In the following code sample, I create an instance from the
Array()
constructor and then augment it with its own property.
Sample: sample27.html
1
2
3
4
5
6
7
8
| <!DOCTYPE html><html lang= "en" ><body><script> var myArray = new Array(); myArray.prop = 'test' ; console.log(myArray.prop) // Logs 'test'. </script></body></html> |
This could be done with
Object()
, RegExp()
, or any of the other non-primitive constructors—even Boolean()
.
Sample: sample28.html
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
| <!DOCTYPE html><html lang= "en" ><body><script> // This can be done with any of the native constructors that actually produce an object. var myString = new String(); var myNumber = new Number(); var myBoolean = new Boolean( true ); var myObject = new Object(); var myArray = new Array(); var myFunction = new Function( 'return 2+2' ); var myRegExp = new RegExp( '\bt[a-z]+\b' ); myString.prop = 'test' ; myNumber.prop = 'test' ; myBoolean.prop = 'test' ; myObject.prop = 'test' ; myArray.prop = 'test' ; myFunction.prop = 'test' ; myRegExp.prop = 'test' ; // Logs 'test', 'test', 'test', 'test', 'test', 'test', 'test'. console.log(myString.prop, myNumber.prop, myBoolean.prop, myObject.prop, myArray.prop, myFunction.prop, myRegExp.prop); // Be aware: Instance properties do not work with primitive/literal values. var myString = 'string' ; var myNumber = 1; var myBoolean = true ; myString.prop = true ; myNumber.prop = true ; myBoolean.prop = true ; // Logs undefined, undefined, undefined. console.log(myString.prop, myNumber.prop, myBoolean.prop); </script></body></html> |
Adding properties to objects created from a constructor function sometimes occurs. Remember, object instances created from constructor functions are just plain old objects.
Keep in mind that besides their own properties, instances can have properties inherited from the prototype chain. Or, as we just saw in the previous code sample, properties added to the constructor after instantiation. This highlights the dynamic nature of objects in JavaScript.
The Semantics of "JavaScript Objects" and "Object()
Objects"
Do not confuse the general term "JavaScript objects," which refers to the notion of objects in JavaScript, with
Object()
objects. An Object()
object (e.g., var myObject = new Object()
) is a very specific type of value expressed in JavaScript. Just as an Array()
object is a type of object called array, an Object()
object is a type of object called object. The gist is that the Object()
constructor function produces an empty generic object container, which is referred to as an Object()
object. Similarly, the Array()
constructor function produces an array object, and we refer to these objects as Array()
objects.
In this book, the term "JavaScript objects" is used to refer to all objects in JavaScript, because most of the values in JavaScript can act like objects. This is due to the fact that the majority of JavaScript values are created from a native constructor function which produces a very specific type of object.
Conclusion
What you need to remember is that an
Object()
object is a very specific kind of value. Its a generic empty object. Do not confuse this with the term "JavaScript objects" used to refer to most of the values that can be expressed in JavaScript as an object.
No comments:
Post a Comment