0

I have two JS functions doing the same thing:

1)

var person = {
    firstName: 'John',
    surname: 'Jones',
    dob: new Date('1990-01-01'),
    isMarried: false,
    age: function() {
        return new Date().getFullYear() - this.dob.getFullYear();
    }
};

2)

var person = {
    firstName: 'John',
    surname: 'Jones',
    dob: new Date('1990-01-01'),
    isMarried: false,
    age: () => {
        return new Date().getFullYear() - this.dob.getFullYear();
    }
};

Notice that the only difference between the two pieces of code is how the age() function is described. As I understand, the former is using a function statement and the latter is using a function expression.

The issue is however, that only the former piece of code returns the expected data, whereas the latter returns the following error:

Uncaught TypeError: Cannot read property 'getFullYear' of undefined
    at Object.age

I am trying to understand why one works and the other doesn't when both are syntactically correct?

I've just started out learning JS in depth so detailed yet straight-forward answers would be appreciated. Thank you.

Azhari
  • 535
  • 5
  • 20
  • var person2 = { firstName: 'John', surname: 'Jones', dob: new Date('1990-01-01'), isMarried: false, age: () => { return new Date().getFullYear() - this.person2.dob.getFullYear(); } }; – Hamit YILDIRIM May 21 '19 at 09:09

2 Answers2

1

As described on MDN, arrow functions do not bind to this (in addition to other keywords). In your second case, this is undefined, resulting in the TypeError.

DocMax
  • 12,094
  • 7
  • 44
  • 44
1

As I understand, the former is using a function statement and the latter is using a function expression

No both are function expressions. The only difference is that the first is normal function and second one ES6 Arrow Function.According to MDN

An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this

Arrow function doesn't have their own this bindings to this and it will use the this binded to the parent scope. In above case parent scope is global scope. So this will refer to window object not to object.

const obj = {
  method:() => console.log(this === window)
}

obj.method()
Maheer Ali
  • 35,834
  • 5
  • 42
  • 73