0

I have following piece of code for learning JS.

function CircleArea(x)
{
   this.x = x;
}

CircleArea.prototype = 
{  
   area: function () {
       return 22 / 7 * this.x * this.x;
   }
};

var CalArea = new CircleArea(7);
if( CalArea.constructor === CircleArea.prototype.constructor)
{
   alert(CalArea.area());
}

I decoupled the inheritance chain by assigning an object literal to CircleArea.prototype and then defined CalArea object using CircleArea constructor. Now both CalArea.constructor and CircleArea.prototype.constructor are basically Object constructors rather than CircleArea constructor but when I called CalArea.area() inside alert function this.x obtains 7 as its value whereas value 7 is passed as an argument to CircleArea constructor not to Object constructor to which CalArea.constructor and CircleArea.prototype constructors refer now.

TaoPR
  • 5,932
  • 3
  • 25
  • 35
user2913184
  • 590
  • 10
  • 33
  • 2
    Related: [Why is it necessary to set the prototype constructor?](http://stackoverflow.com/questions/8453887/why-is-it-necessary-to-set-the-prototype-constructor) – Jonathan Lonowski Jun 15 '15 at 02:07
  • 3
    What is your question? – Felix Kling Jun 15 '15 at 02:08
  • The question is when CalArea constructor and CircleArea prototype constructor refer to Object constructor how come calling area() method on CalArea object gets this.x = 7.Although value 7 is passed to CircleArea constructor not Object constructor? – user2913184 Jun 15 '15 at 02:10
  • no both .constructor properties return back Object constructor. – user2913184 Jun 15 '15 at 02:12
  • You make the assumption that the `constructor` property has any significance. It does not. You are explicitly calling `CircleArea`. This will create a new object and set `x` to the value passed in. The object will inherit from `CircleArea.prototype`, which provides the `area` method. That's all there is to it. Did you expect that although you are *explicitly* calling the function `CircleArea`, `Object` would be called instead? That would be indeed strange. – Felix Kling Jun 15 '15 at 02:14
  • 3
    @user2913184 The constructor function being used is still `CircleArea`, since that's what's being provided to the `new` operator, regardless of the `constructor` property's value. That property has no bearing on how the instance is created. It's only meant to be informational. [What it the significance of the Javascript constructor property?](http://stackoverflow.com/questions/4012998/what-it-the-significance-of-the-javascript-constructor-property) – Jonathan Lonowski Jun 15 '15 at 02:14
  • @Bergi Function.prototype is CircleArea's prototype but CircleArea.prototype is CalArea's prototype. Even when I debug the above code inside "if" statement CalArea.constructor and CircleArea.prototype.constructor both give me back function Object(){ [native code]}. – user2913184 Jun 15 '15 at 02:15
  • 2
    Wow, it's been a while since I saw 22/7 used for PI, especially given that JavaScript [defines PI for you](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/PI). – nnnnnn Jun 15 '15 at 02:44
  • Well I was in a hurry but thanks for reminding me Math.PI – user2913184 Jun 15 '15 at 02:48

2 Answers2

0

I'm not sure what you mean by "decoupled the inheritance chain" but to me, what you are experiencing is the expected behavior.

You call area() on an instance of CircleArea.

area() uses this.x.

this in that context is your instance of CircleArea that has x=7.

So your calculation is 22 / 7 * 7 * 7

If you are expecting something different, could you explain what you expect and why you expect it?


I am guessing that your confusion stems from this which is set to the object instance that a function is called on, so calling CalArea.area() means that this is set to CalArea so this.x is the same as CalArea.x

CodingWithSpike
  • 42,906
  • 18
  • 101
  • 138
  • Well I kinda know what your point is but my confusion is that when CalArea.constructor is an Object constructor not CircleArea constructor the how come an argument passed to CircleArea constructor is supplying value to an object CalArea whose constructor is Object not CircleArea – user2913184 Jun 15 '15 at 02:19
  • 1
    @user2913184: I suggest you set `CircleArea.prototype.constructor = function Foo() {}`, **after** you created `CalArea` and then have look at `CalArea.constructor`. According to your logic, `CalArea` should have been constructed by `Foo`, but we both know that this is not the case. `CalArea.constructor` simply refers to `CircleArea.prototype.constructor` and that value plays no part in the construction of the object itself. – Felix Kling Jun 15 '15 at 02:25
  • So you mean though CalArea constructor will be Foo constructor but it actually plays no part in the construction of CalArea itslef. Am I right sir? – user2913184 Jun 15 '15 at 02:32
  • Also I have seen that if I assign a property like CircleArea.prototype.area = function(){}, then define CalArea, now CalArea and CircleArea.prototype.constructor will be both refer to CircleArea constructor but CalArea.area() will return me a number in terms of circle area and CircleArea.prototype.area() will give me back NaN. I guess though CircleArea is constructor for both CalArea and CircleArea.prototype but only CalArea is it's instance not CircleArea.prototype, hence area is getting calculated for CalArea not CircleArea.prototype. – user2913184 Jun 15 '15 at 02:44
0

When you assign an object to prototype (CircleArea.prototype = {area: fun..}) you just dispatch default CircleArea.prototype hence CircleArea.prototype.constructor dispatched too. But CircleArea still is constructor when you use operator new it returns an object instance of CircleArea ({x: argument, proto: { area: fun, proto:...}}). You just can't use new CalArea.constructor() but can new CircleArea(). new CalArea.constructor() returns the Object instance

Artem Zanko
  • 73
  • 1
  • 5