0
const user = {
    name: "Praveen",
    videos: ["html", "css", "js"],
    
    greet() {
        console.log(`welcome ${this.name}`);
        const getVideos = () => {
            console.log(`You have ${this.videos.length} videos`);
        };
        getVideos();
      },
    };
user.greet();

I am able to access the value of the videos.length in the above code (I have used arrow function), but I am not able to access the value of the videos.length in the below code:

const user = {
    name: "Praveen",
    videos: ["html", "css", "js"],
    
    greet() {
        console.log(`welcome ${this.name}`);
        const getVideos = function () {
          console.log(`You have ${this.videos.length} videos`);
        };
        getVideos();
      },
    };
user.greet();

JKD
  • 1,279
  • 1
  • 6
  • 26
SB Praveen
  • 49
  • 6

3 Answers3

1

getVideos() is called with no context, therefore this refers to the window object.

The preferred way to get around this is using an arrow function, as seen in your first example.

A pre-arrow function way was to do something like this:

const user = {
  name: "Praveen",
  videos: ["html", "css", "js"],

  greet() {
    console.log(`welcome ${this.name}`);
    const that = this;  // <---- that now refers to this context
    const getVideos = function () {
      console.log(`You have ${that.videos.length} videos`);   // <--- use that instead of this
    };
    getVideos();
  },
};
Rezaa91
  • 500
  • 2
  • 10
1

Function defined with keyword function will has its own this, while arrow function doesn't (doc)

So in your case, when you use arrow function in example 1, the this will refer to user, while in example 2, this will refer to getVideos

To resolve this, you could store this of the user into a new variable

const user = {
  name: "Praveen",
  videos: ["html", "css", "js"],

  greet() {
    console.log(`welcome ${this.name}`)
    const self = this // notice me
    const getVideos = function () {
      console.log(`You have ${self.videos.length} videos`)
    }
    getVideos()
  },
}
user.greet()

Or use call and then apply the this reference of user to getVideos

const user = {
  name: "Praveen",
  videos: ["html", "css", "js"],

  greet() {
    console.log(`welcome ${this.name}`)
    const getVideos = function () {
      console.log(`You have ${this.videos.length} videos`)
    }
    getVideos.call(this) // notice me
  },
}
user.greet()
hgb123
  • 13,869
  • 3
  • 20
  • 38
0

Here you should use arrow functions. here is the HTML code with JavaScript will work

<!DOCTYPE html>
<html>
<head>
<script>
       const user = {
      name: "Praveen",
      videos: ["html", "css", "js"],
    
      greet() {
        console.log(`welcome ${this.name}`);
        const getVideos = () => {
          console.log(`You have ${this.videos.length} videos`);
        };
        getVideos();
      },
    };
    user.greet();
</script>
</head>
<body>

</body>
</html>