-1

In sendTo method of user I tried to bind earlier defined function and send this.name as the first argument. But if i try console logging, this.name returns undefind. How to correctcly bind context of user's object to sendTo() mehtod?

function sendFrom(from, to, text) {
    console.log(this);
    return `${from}'s packet --> ${to}  \nmessage: ${text}`;
}

let user = {
    name: "Alex",
    sendTo: sendFrom.bind(this, this.name),
}


user.sendTo = user.sendTo.bind(user);

console.log(user.sendTo("John", "some message"));
{}
undefined's packet --> John  
message: some message
shevy
  • 1
  • 4
  • Shouldn't it be `user.sendTo.bind(this, user)` ? – Jeremy Thille Oct 13 '21 at 08:12
  • @JeremyThille If i use user.sendTo.bind(this, user), it seems to bind whole user object to second argument of sendFrom() `undefined's packet --> [object Object]` – shevy Oct 13 '21 at 08:15
  • 1
    Object literals do not create a scope, i.e. `this` doesn't refer to the object literal (the object doesn't even exist at that point). This has nothing to do with using `.bind`. – Felix Kling Oct 13 '21 at 08:28

2 Answers2

2

I guess you can achieve expected behavior by not using any bindings:

function sendFrom(to, text) {
    console.log(this);
    return `${this.name}'s packet --> ${to}  \nmessage: ${text}`;
}

let user = {
    name: "Alex",
    sendTo: sendFrom
}

console.log(user.sendTo("John", "some message"));

But if you want to execute the user's method somewhere else that when binding comes into play:

let alexeSendTo = user.sendTo
alexesSendTo('John', 'Hey John!') // it will loose Alex's user context link

let alexeSendTo = user.sendTo.bind(user)
alexesSendTo('John', 'Hey John!') // now it is marked as Alex message
  • 1
    I'm actually trying to understand how the context works in binded function. So this example is good, but it is not what i want to achieve. But thank you for your answer anyways! – shevy Oct 13 '21 at 08:24
  • 1
    @shevy have a look at my answer for an explanation. To let you know, there is not a need of binding here and this might not be the best example. Dmitrii's code is the correct and simplest way to do it – Tushar Shahi Oct 13 '21 at 08:29
  • 1
    @TusharShahi Ok, thank you. p.s. I was just experementing with JS, most likely i will never face this example in production. I just wanted to have a clearier view on JS context behaviour. :) – shevy Oct 13 '21 at 08:32
2

To undersand why this does not work you have to look at the user object:

sendTo: sendFrom.bind(this, this.name),

This property inside user is what is causing the issue. When this code is run this belongs to the window object and not the user.

So finally sendTo is a method with context as window and first param as window.name

That is why console.log(this) returns the window object.

When you do this: console.log(user.sendTo("John", "some message"));

You are adding the params "John" and "some message" after the already appended param.

So finally params become:

from, to, text -> window.name(undefined in your case), John, some message

Anytime you are using this in this code it is referring to window. There is actually no way to understand binding here and this example is not where you should be using bind

Tushar Shahi
  • 16,452
  • 1
  • 18
  • 39
  • Yeah, thank you. I figured out why it works like that. But can you please explain how can i apply a current object's context within it? – shevy Oct 13 '21 at 08:28
  • 1
    @shevy: [Self-references in object literals / initializers](https://stackoverflow.com/q/4616202/218196) – Felix Kling Oct 13 '21 at 08:33
  • 1
    @shevy as mentioned in the above answer comment, adding bind and all here is over engineering and will not show you the way bind works. Look at Felix's link – Tushar Shahi Oct 13 '21 at 08:34