compare code 1 and code 2, which one is correct?
function Rectangle(height, width) {
this.height = height;
this.width = width;
this.calcArea = function() { // why use this here?
return this.height * this.width;
};
}
code 2 I thought it's fine with this :
function Rectangle(height, width) {
this.height = height;
this.width = width;
calcArea = function() {
return this.height * this.width;
};
}
This depends on how you view "correct":
calcArea
?Rectangle
class but you can make it calculate correctly with a bit of difficulty ad redirection. See below.Code 1 -
calcArea()
If you create a new instance of the
Rectangle
in code 1 then:Will correctly output
12
Code 2 -
calcArea()
If you create a new instance of the
Rectangle
in code 2 then:Will throw an error:
TypeError: rect.calcArea is not a function
calcArea
is, instead, attached to the global scope so we can do:console.log( calcArea() );
Will output
NaN
ascalcArea
in part of the global scope so has no knowledge of any instance of aRectangle
class and the global scope does not have aheight
or awidth
attribute.If we do:
Then it will return
70
(and not12
since, withincalcArea()
,this
references the global scope and not therect
object).If we change what
this
refers using.call()
to invoke the function:Then it will output
12
(sincethis
now refers to therect
object and not to the global scope).You probably don't want to have to do this every time you want to use
calcArea()
.Why Code 1 is not optimal
Code 1 will work but is not the optimal solution because each time you create a new
Rectangle
object it will create ancalcArea
attribute of that object which is a different function to anycalcArea
attributes of any otherRectangle
object.You can see this if you do:
Which will output
true
when testing the string representation of the functions are identical butfalse
when testing whether the functions are identical.What does this mean? If you create 10,000 instances of
Rectangle
then you will have 10,000 different instances of thecalcArea
attribute as well and each copy will require additional memory (plus time to allocate that memory and to garbage collect it at the end).What is better practice?
Then if you do:
It will return
true
for both - meaning thatr1.calcArea
andr2.calcArea
refer to the identical function and regardless of how many instances ofRectangle
there are.When you preface your methods and properties with 'this' in your constructor they allow any new objects that get created with that constructor to use those properties and methods and have those properties and methods point to the newly created object.
If you create a new object based on your version of the Rectangle constructor that doesn't use 'this' as a preface to calcArea and look at the chrome debugger you get the following error:
In short it simply isn't recognized.
The other aspects of not using "this" is that the method becomes 'global'.
Here is a code example to demonstrate:
If you don't use
this
,calcArea
will not be accessible through the object of Rectangle. When you say,you create a new variable in the current object (
this
) and the function will be assigned to it, so that the object will have access to it.Try these statements, with and without
this
. You ll understand better.The second version will set the global variable calcArea to do stuff specific to your object whenever an instance of your object is constructed. Use of this is required to set properties of your particular object.