0
var now = 2018;

function calculateAge(yearOfBirth) {
    return now - yearOfBirth;
}

var Josh = {
    dateOfBirth: 1990,
    age: calculateAge(this.dateOfBirth),
}

console.log(Josh.age);

Why can't I use a key as an argument in a function? If I put normal number there it works fine but I can't understand why that way doesn't. Does it have something to do with recursion or scope?

realisTT
  • 9
  • 1

4 Answers4

2

The reason is that in this statement:

var Josh = {
    dateOfBirth: 1990,
    age: calculateAge(this.dateOfBirth),
}

this does not refer to Josh, or to the object that will become Josh. There's no way it could, because none of these things exist yet when this statement executes.

In this statement this refers to whatever it refers to in any other statement in that scope.

console.log(this);                         // <-- same this
var Josh = {
    dateOfBirth: 1990,
    age: calculateAge(this.dateOfBirth),   // <-- same this
}
console.log(this.someProperty);            // <-- same this

If the this in that scope doesn't have a dateOfBirth property of 1990, you're not going to get the result you're expecting.

If you want to avoid having to repeat the 1990 value, then store it in a variable, and reference that variable:

var dob = 1990;
var Josh = {
    dateOfBirth: dob,
    age: calculateAge(dob)
};
JLRishe
  • 99,490
  • 19
  • 131
  • 169
1

In addition to other good answers, you could also achieve the behaviour you're looking for by simply having a getter for the age property:

function calculateAge(yearOfBirth) {
    return 2018 - yearOfBirth;
}

var Josh = {
    dateOfBirth: 1990,
    get age() {
        return calculateAge(this.dateOfBirth);
    }
}

Josh.age; // > 28

An additional bonus to this approach is that Josh.age is calculated in real-time when accessed, and thus it will always be in sync with Josh.dateOfBirth:

Josh.age; // > 28
Josh.dateOfBirth = 1988;
Josh.age; // > 30
JJWesterkamp
  • 7,559
  • 1
  • 22
  • 28
0

The problem

For example: Imagine this is the only line of code in your Javascript file

// In web browsers, the window object is also the global object:
console.log(this === window); // true

The example above shows how this behaves, the value of this dependents of its context.

The use of this in your code isn't referencing to your object Josh it's referencing to either the current called function or global context.

If you try to print this as follow console.log(this) you will realize that this has a value from a different context than Josh's.

The solution

  • Create an instantiable Object with those attributes, and you will be able to use this which has Josh's context:
var Josh = function() {
   this.dateOfBirth = 1990,
   this.age = calculateAge(this.dateOfBirth)
};

Look this code snippet:

var now = 2018;

function calculateAge(yearOfBirth) {
  return now - yearOfBirth;
}

var Josh = function() {
  this.dateOfBirth = 1990,
  this.age = calculateAge(this.dateOfBirth)
};

console.log(new Josh().age);

See, now it's passing the right value to your function calculateAge.

halfer
  • 19,824
  • 17
  • 99
  • 186
Ele
  • 33,468
  • 7
  • 37
  • 75
-2

Give it a try,

var now = 2018;

var Josh = {
    dateOfBirth: 1990,
    age: function () {
        return (now - this.dateOfBirth);
    }
}

console.log(Josh.age())
Nilesh Singh
  • 1,750
  • 1
  • 18
  • 30