Is you baffled (obstruction; confuse) by the new
operator in JavaScript? Wonder What's the difference between a function and a constructor is? Or What the heck a prototype was used for?
I ' m going to lay it out straight.
Now, there's been a lot of talk for a long time about so-called "pseudo-classical" JavaScript. Mostly, the new guard of JavaScript folk don ' t like to use the new
keyword. It was written into the language to act more like Java, and its use is a little confusing. I ' m not going to take sides here. I ' m just going to explain how it works. It ' s a tool; Use it if it ' s practical.
What is A CONSTRUCTOR?
A constructor is an any function which is used as a constructor. The language doesn ' t make a distinction. A function can is written to being used as a constructor or to being called as a normal function, or to is used either the.
A constructor is used with the new
keyword:
var function Vehicle () { // ... }varnew Vehicle ();
What happens if A CONSTRUCTOR is called?
When new Vehicle()
was called, JavaScript does four things:
- It creates a new object.
- It sets the property of the
constructor
object to Vehicle
.
- It sets up the object to delegate
Vehicle.prototype
.
- It calls in the context of the
Vehicle()
new object.
The result of Is this new Vehicle()
new object.
1. IT creates the NEW OBJECT.
This is nothing special, just a fresh, new object: {}
.
2. IT Sets the
CONSTRUCTOR
property of the OBJECT to
VEHICLE
.
This means the things:
Vehicle.constructor = = Vehicle // trueinstanceof vehicle // True
This isn ' t a ordinary property. It won ' t show up if you enumerate the properties of the object. Also, you can try to set constructor
, but you'll just set a normal property on top of the this special One. To wit:
vehicle; // {} var fuzzybear = function Fuzzybear () {};vehicle.constructor = fuzzybear;vehicle; // {constructor:function fuzzybear ()} Vehicle.constructor = = Fuzzybear; // vehicle // false vehicle instanceof Vehicle //
The underlying, built in property are constructor
something you can ' t set manually. It can only is set for you, as part of the construction with the new
keyword.
To avoid many novices forgetting to use the New keyword, the factory method is provided, but at this point you have to worry about type comparisons:
<script type= "Text/javascript" >functionFoo () {}varFoo =Newfoo (); Console.log (fooinstanceofFoo);//truefunctionFoo2 () {functionInnerFoo2 () {}return NewInnerFoo2 ();}varFoo2 =NewFoo2 (); Console.log (Foo2instanceofFOO2);//falsefunctionFoo4 () {}functionFoo3 () {functionInnerFoo3 () {}//InnerFoo3.prototype.constructor = Foo3; return NewInnerFoo3 ();}varFoo3 =NewFoo3 (); Console.log (Foo3instanceofFOO3);//falseConsole.log (Foo3.constructor);//truefunctionFoo4 () {}functionFoo5 () {functionInnerFoo5 () {} Innerfoo5.prototype=NewFoo4 (); return NewInnerFoo5 ();}varFoo5 =NewFoo5 (); Console.log (Foo5instanceofFOO4);//true</script>
3. IT sets up the OBJECT to DELEGATE to
VEHICLE.PROTOTYPE
.
Now it gets interesting.
A function is just a special kind of object, and a function can has the properties of any object A. Functions automatically get a property called prototype
, which was just an empty object. This object gets some special treatment.
When a object is constructed, it inherits all of the properties of its constructor ' s prototype. I know, it ' s a brainful. here.
Vehicle.prototype.wheelCount = 4; var New Vehicle;vehicle.wheelcount; // 4
The Vehicle instance picked up the wheelCount
from Vehicle
' s prototype
Now this "inheritance" was more than simply copying properties to the new objects. The object is set up to delegate any properties which haven ' t been explicitly set up to its constructor ' s prototype. That means that we can change the prototype later, and still see the changes in the instance.
Vehicle.prototype.wheelCount = 6; vehicle.wheelcount; // 6
But if we do, we can always override it.
Vehicle.wheelcount = 8; vehicle.wheelcount // 8(new Vehicle ()). Wheelcount // 6;
We can do the same thing with methods. After all, the A method is just a function assigned to a property. Check it.
function return "Vroom!" };vehicle.go (); // "vroom!"
4. IT CALLS
VEHICLE()
In the CONTEXT of the NEW OBJECT.
Finally, the constructor function itself is called. Inside the function, is set to the this
object we ' re constructing. (Why?) Because that's what Java does.) So,
var function Vehicle (color) { this. Constructor; // function Vehicle () this. color = color;} (New Vehicle ("Tan")). Color; // "Tan"
Side Note:above, I said the use of the new
keyword returned the constructed object. This is correct unless the constructor returns something explicitly. Then this object is returned, and the constructed object is just dropped. But really. JavaScript slaves over a hot CPU to the Create this object for do you just throw it away? Rude. And confusing to people who use your constructor. So unless you have a really good reason, and don ' t return anything from constructor functions.
Putting IT all TOGETHER
Given This tool, here's one-to-the-intended-to-implement something like classes in JavaScript .
// Class Definition/constructor var function Vehicle (color) { // initializationthis . color = color;} // Instance Methods Vehicle.prototype = { function go () { return "vroom!" ; }}
"Subclassing"
This "pseudoclassical" style doesn ' t has an exact-to-make subclasses, but it comes close. We can set the prototype of our "subclass" to an instance of the "superclass".
varCar =functionCar () {}; Car.prototype=NewVehicle ("Tan"); Car.prototype.honk=functionHonk () {return"Beep!" };varCar =NewCar (); Car.honk (); //"beep!"Car.go ();//"vroom!"Car.color;//"Tan"CarinstanceofCar;//trueCarinstanceofVehicle;//true
Now, there's a problem here. Vehicle
The constructor only gets called once and to set up Car
' s prototype. We need to give it a color there. We can ' t make different cars has different colors, which is not ideal. Some JavaScript frameworks has gotten around this by defining their own implementations of classes.
And for MY last TRICK ...
Sometimes you don ' t want a notion of classes. Sometimes just want one object to inherit the properties of another (but is able to override them). This is what most prototype-based languages work, and not JavaScript. At least, not without a little massaging.
This function lets us accomplish it. It's been tossed around for a long time and are sometimes called " create
" and sometimes " clone
" and sometimes other things.
functionCreate (parent) {varF =function() {}; F.prototype=parent; return NewF ();}varMasterobject = {A: "Masterobject value"}varObject1 =Create (masterobject);varObject2 =Create (masterobject);varOBJECT3 =Create (masterobject);varobject3.a = "Overridden Value"; object1.a;//"Masterobject value"object2.a;//"Masterobject value"object3.a;//"Overridden Value"masterobject.a= "New Masterobject value"object1.a;//"New Masterobject value"object2.a;//"New Masterobject value"object3.a;//"Overridden Value"
You said A mouthful.
The JavaScript prototype chain is a little different than how to most languages work and so it can be tricky understand. It doesn ' t make it all easier when JavaScript gets syntax that makes it looks more like other languages, like inheriting J Ava ' s new
operator. But if you know the what's your ' re doing, you can do some crazy-cool things with it.
<script type= "Text/javascript" >functionFather () { This. Name = ' father Name ';} Father.prototype.get_name=function(){ return This. Name;functionSon () {}son.prototype=NewFather ();varson =NewSon (); Son.name= ' son name '; Console.log (Son.get_name ());//test the behavior after overriding the attributes of the parent classDeleteSon.nameconsole.log (Son.get_name ());</script>
JavaScript constructors, prototypes, and the ' new ' keyword