Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can you change the this with call and apply? #52

Open
matthewp opened this issue Feb 24, 2022 · 9 comments
Open

Can you change the this with call and apply? #52

matthewp opened this issue Feb 24, 2022 · 9 comments

Comments

@matthewp
Copy link

I think the answer is that you can, but it was unclear to me from the examples. For example:

const introduceBob = bob.introduce~();
introduceBob();

What if you do:

const introduceBob = bob.introduce~();
introduceBob.call(barbara);

I assume the this in introduce refers to barbara and not bob, correct?

@matthewp
Copy link
Author

Actually reading the entire readme and I'm really unsure, especially given the semantics: https://github.com/tc39/proposal-partial-application#semantics

How can I partially apply a function who's this value is determined by the caller (via call/apply)?

@ljharb
Copy link
Member

ljharb commented Feb 24, 2022

I would assume that introduceBob is a bound function, and thus can not have the receiver changed with call and apply.

@matthewp
Copy link
Author

Thanks, that's my interpretation after rereading the semantics as well. Could you create an unbound version some how? Maybe like this?

const introduceBob = bob.introduce.call~(?);
introduceBob.call(barbara);

@ljharb
Copy link
Member

ljharb commented Feb 24, 2022

Yes, but in that case it'd be introduceBob(barbara).

@ljharb
Copy link
Member

ljharb commented Feb 24, 2022

If you want it to work with .call and .apply, you need to use a normal function, like const introduceBob = function (...args) { return bob.introduce.call(this, ...args); };

@matthewp
Copy link
Author

Hm, I'm a little confused, that doesn't use this new syntax proposal. Are you saying that you can't use this new syntax and then use call/apply on the created function to pass the this value?

@ashwell
Copy link

ashwell commented Feb 24, 2022

I think what @ljharb is getting at is your example would be this,

const introduceBob = bob.introduce.call~(?);
introduceBob(barbara);

because introduceBob would be a partially applied version of introduce.call not introduce. The other point is that bob.introduce would need to be a normal function, not an arrow or bound function.

edit: I might be wrong as I am just a random dude on the internet.

@ljharb
Copy link
Member

ljharb commented Feb 24, 2022

Right you can't use this proposal's syntax, and end up with a normal function whose receiver can be dynamically changed via .call/.apply

@matthewp
Copy link
Author

matthewp commented Feb 24, 2022

Ok, thanks for the clarity there. Then fn.call~(?) is a bit of a workaround. Maybe an acceptable one, I'm not sure yet.

@ashwell My example was taken from the readme which is:

const bob = {
  name: "Bob",
  introduce() {
    console.log(`Hello, my name is ${this.name}.`);
  }
};

This function can have call/apply used on it.


From the readme it sounded like the proposal wanted to fix the issue with .bind() that you need to know the this value ahead of time, but it sounds like it doesn't. This is one of the biggest disadvantages to bind() that I often find.

So I guess this thread should turn into a request that this feature be considered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants