0

I am trying to set up a javascript object with one of it's items being a function. I am doing a little bit of self reference and it is not working.

var onTimePoints = function($a, $b, $c, $lifeotr){

    $var1 = ($b - $a) / $c;
    $var2 = ($lifeotr - $a) / $var1;
    if($var2>$c)
    {
    $var2 = $c;
    }
    if($var2<0)
    {
    $var2 = 0;
    }
    $var2 = Math.round($var2);
    return $var2;
}
var lifeData ={
      min: 25000,
      max: 65000,
      otr: 56426,
      maxPoints:100,
      otp: onTimePoints(25000, 65000, 100, 56426),
      test: function(){
        alert(this.min);
      }
}

When I do conosle.log(lifeData.otp) it works.

When I replace the hard coded numbers with this.min, this.max, etc... it doesn't work.

Here is an example of what doesn't work:

var lifeData ={
  min: 25000,
  max: 65000,
  otr: 56426,
  maxPoints:100,
  otp: onTimePoints(this.min, this.max, this.maxPoints, this.otr),
  test: function(){
    alert(this.min);
  }
}

In this case console.log(lifeData.otp) returns NaN.

I am sure that I am just overlooking something. Appreciate if you know the issue.

I Hate Lazy
  • 47,415
  • 13
  • 86
  • 77
Spencer Cooley
  • 8,471
  • 16
  • 48
  • 63
  • 3
    I deleted my original comment but then I realized I was right :-) The value of `this` has nothing whatsoever to do with an under-construction object literal. It has to do solely with function invocation context. Basically there's no direct way to do what you're doing in JavaScript. You have to use a separate statement. – Pointy Oct 11 '12 at 18:19
  • When I alert this.min it alerts 25000. I am assuming that this.min is the same as saying lifeData.min – Spencer Cooley Oct 11 '12 at 18:19
  • `this` is `window`, not `lifeData`. – jbabey Oct 11 '12 at 18:20
  • 1
    It is, but that's *inside* that "test" function call. When you call `lifeData.test()`, it's that function call itself that ensures that `this` inside the function is set to refer to the "lifeData" object. However, that's *not* the case in the midst of the object literal that initializes the object. In that context, `this` has a value determined by the context of that `var` declaration. – Pointy Oct 11 '12 at 18:21
  • @My_Boon No, it's not working. Try calling `lifeData.otp;` and you'll see that you get a `NaN` back. – Pointy Oct 11 '12 at 18:22
  • oops. formula is a placeholder variable that I have set earlier in my script. Forgot to take it out before I posted. I will fix it. – Spencer Cooley Oct 11 '12 at 18:22
  • Now another possibility is to make the "otp" property be a *wrapper*: `otp: function() { onTimePoints(this.min, this.maxPoints, ... ); }` – Pointy Oct 11 '12 at 18:23
  • possible duplicate of ["this" inside object](http://stackoverflow.com/questions/7043509/this-inside-object) – Bergi Oct 11 '12 at 18:25

2 Answers2

5

You will get a lot of tutorials to understand this, but here I am trying to illustrate it using a few lines of code. In firebug console or Chrome console do the following

  1. enter this and press enter

    > Window // Now it is global scope

  2. Run the following code

    this.a = 500;
    this.b = 600;
    
  3. Now run the following code;

    var MyObject = {
        a: 20,
        b: 40,
        sum: this.a + this.b,
        getSum: function(){
            return this.a + this.b;
        }
    }
    
  4. Now run the following

       MyObject.sum
    

    > 1100 // because MyObect is declared in global scope and in the expression sum:this.a+this.b this is Window object. so sum: 400 + 500

  5. Now run

       MyObject.getSum();
    

    > 60 // because getSum is a method of MyObject. And when invoked like MyObject.getSum() inside the getSum this will be MyObject. so it returns 20 + 40

Diode
  • 24,570
  • 8
  • 40
  • 51
1

You can't do what you're trying to do.

Consider:

var lifeData ={
  min: 25000,
  max: 65000,
  otr: 56426,
  maxPoints:100,
  otp: onTimePoints(25000, 65000, 100, 56426),
  otNewcomm: formula,
  test: function(){
    alert(this.min);
  }
}

or

var min = 25000;
var max = 65000;
var otr = 56426;
var maxPoints = 100;
var lifeData ={
  min: min,
  max: max,
  otr: otr,
  maxPoints: maxPoints,
  otp: onTimePoints(min, max, maxPoints, otr),
  otNewcomm: formula,
  test: function(){
    alert(this.min);
  }
}

or

function lifeData(min, max, otr, maxPoints)
{
    this.min = min;
    this.max = max;
    this.otr = otr;
    this.maxPoints = maxPoints;
    this.otp = onTimePoints(min, max, maxPoints, otr);
    ...
}
var lifeDataInstance = new lifeData(25000, 65000, 56426, 100);
Paul Fleming
  • 24,238
  • 8
  • 76
  • 113
  • 1
    Or possibly the "otp" property could be a function wrapper around a call to "onTimePoints". – Pointy Oct 11 '12 at 18:24
  • 1
    The last chunk is what I am using because i am going to be creating a new instance every time an event is fired. It is to refresh the view with the correct numbers. Seems like the best solution. – Spencer Cooley Oct 11 '12 at 18:39