1

function makeUser() {
  return {
    name: "John",
    ref() {
      return this;
    }
  };
}

let user = makeUser();

alert(user.ref().name);

From what I've learned from thistutorial, they define as the object before dot and since this is the return value of the function, I thought it would be user.

And this tutorial is defining it as the object that is executing the current function.

I think the object that is executing the current function is user. When you replace this by its value it becomes alert(user.user.name);.

Superhuman
  • 61
  • 7
  • I don't understand the sentence "Isn't alert at runtime become something like alert(user.user.name);?". Can you rephrase it, please? – Armen Michaeli Oct 29 '21 at 11:03
  • the `.name` accessor is applied to the `return` value of `user.ref()`. An explicit rewriting would be `(user.ref()).name` – pilchard Oct 29 '21 at 11:04
  • `user.ref()` evaluates to `user` (`user.ref() === user`) , so it's more like performing `user.name` – Nick Parsons Oct 29 '21 at 11:05
  • @NickParsons What difference does it make to use `.ref()` and not use it at all? – Superhuman Oct 29 '21 at 11:21
  • @Superhuman There shouldn't be any differences between using `user.ref()` vs using `user` directly. – Nick Parsons Oct 29 '21 at 11:31
  • 1
    @Superhuman the main idea of your piece of code is to show that the value of `this` inside of `ref()` is equal to the object the method was called from - _"the value of `this` is set to the object before dot ."_, in this case that is `user` – Nick Parsons Oct 29 '21 at 11:50

2 Answers2

4

The value of "this" doesn't refer to the name of an object, it refers to the object itself. So there is no "duplication" here, you're just returning an object, which happens to be the same object you started with.

This is perhaps clearer if you separate things out:

function makeUser() {
  // Create an object
  let myObject = {
    name: "John"
  };
  // Create a function which returns that object
  let myFunction = function(){ return myObject; };
  // Store the function on the object
  myObject.ref = myFunction;
  // Return the new object
  return myObject;
}

// Create an object
let user = makeUser();

// Get the name from the object
alert(user.name);

// Call the ref() function, which happens to return the same object
let otherUser = user.ref();
// Get the name again
alert(otherUser.name);

// No matter how many times you call .ref() it will return the same object
alert(user.ref().ref().ref().ref().name);
IMSoP
  • 89,526
  • 13
  • 117
  • 169
  • I think I get a bit what you mean. Something else, I don't quite get is why is when I use `this` as a property value in the object, I get `undefined` as result. Example: ` function makeUser() { return { name: "John", ref: this }; } let user = makeUser(); alert( user.ref.name );` – Superhuman Oct 29 '21 at 11:37
  • 1
    @Superhuman Again, if you break it down, it may make more sense: `function makeUser() { let firstObject=this; let secondObject { name: "John", ref: firstObject }; return secondObject; }` - `this` gets looked up _before secondObject exists_ so must refer to something else. – IMSoP Oct 29 '21 at 12:56
  • 1
    @Superhuman see [Self-references in object literals / initializers](https://stackoverflow.com/q/4616202). Short version is that `this` doesn't refer to the object which is *currently being created*. Because that object doesn't exist yet. See also [How does the "this" keyword work?](https://stackoverflow.com/q/3127429) for what `this` would refer to. – VLAZ Oct 29 '21 at 12:56
0

this refers to a object the function function belongs to or window object if it belongs to no objects. in this case ref() function is returning the owner object for e.g.,

when you call ref() it will return like this

{ name: 'John', ref: [Function: ref] }
abhi patil
  • 504
  • 2
  • 11