4
var mySelf = {
  name: "dina",
  job: "Programmer",
  yearOfBirth: 1993,
  age: () => 2019 - this.yearOfBirth
};

let result = mySelf.age();

console.log(result);

the result is NaN

please help me what actually happened?

pushkin
  • 9,575
  • 15
  • 51
  • 95
Dewa Prabawa
  • 497
  • 2
  • 11

4 Answers4

7

The arrow function inherit the enclosing context (that is Window in this case) rather then the object context, use a plain function instead.

var mySelf = {
  name: "dina",
  job: "Programmer",
  yearOfBirth: 1993,
  age: function() { return 2019 - this.yearOfBirth }
};
    
let result = mySelf.age();
    
console.log(result);

To show that an arrow function receives a lexical this -

const o =
  { func: () => this === window }
  
console.log(o.func()) // true
Karim
  • 8,454
  • 3
  • 25
  • 33
3

If use the name mySelf instead of this(because it will not reference the object in this case) to reference your object it seems to work fine.

var mySelf = {
  name: "dina",
  job: "Programmer",
  yearOfBirth: 1993,
  age: () => 2019 - mySelf.yearOfBirth
};

let result = mySelf.age();

console.log(result);
Scath
  • 3,777
  • 10
  • 29
  • 40
2

One of the property of the arrow function is that the context used in the function is the upper context. So this.yearOfBirth refer to a context when yearOfBirth do not exist (the document context).


Also do not use 2019 statically. 2020 is closer than you think.


const mySelf = {
  name: 'dina',
  job: 'Programmer',
  yearOfBirth: 1993,

  age: () => Number(new Date().getFullYear()) - this.yearOfBirth,
};

const result = mySelf.age();

console.log(result);

To make it work you can use a regular function.

const mySelf = {
  name: 'dina',
  job: 'Programmer',
  yearOfBirth: 1993,

  age: function() { 
     return Number(new Date().getFullYear()) - this.yearOfBirth;
  },
};

const result = mySelf.age();

console.log(result);
Orelsanpls
  • 22,456
  • 6
  • 42
  • 69
0

this is not captured in this context with an arrow function. That's actually the main difference with the classic function way of defining functions.

This means that the this does refer to the global object (windowin a browser) when you actually execute it in your example.

Since there is no global yearOfBirth binding, this.yearOfBirth will return undefined, and any math performed with undefined gives NaN.


A simple solution would be to use a function instead function() {return 2019 - this.yearOfBirth}. (see executable examples in other answers)

You can also use a more "object oriented" approach by using the ES2015 class keyword, in this case the arrow function will behave as you expected.

class Person {
  name = "dina";
  job = "Programmer";
  yearOfBirth = 1993;
  age = () => 2019 - this.yearOfBirth;
}

let mySelf = new Person

console.log(mySelf.age());
Pac0
  • 21,465
  • 8
  • 65
  • 74