如何使用bind方法重写已绑定函数的this值
getGreeting doesn't change the context? The key issue here is that once a function is bound with bind(), it can't be re-bound to a different this context later. Let's break down what's happening in your code step by step:
1. The initial binding in the constructor
In the Salutation constructor, you run:
this.getGreeting = this.getGreeting.bind(this)
This takes the original getGreeting method from the class prototype, creates a new function permanently bound to the current Salutation instance (your salutation object), and assigns it back to this.getGreeting.
From this moment on, salutation.getGreeting is no longer the unbound prototype method—it's a locked-in function that will always use the salutation instance as its this value, no matter how you try to re-bind it later.
2. Why subsequent bind() calls do nothing
When you try:
boundFunction = salutation.getGreeting.bind(myName); boundFunction(); // Still logs "My name is Mike"
You're attempting to re-bind a function that's already been bound. The bind() method ignores any later attempts to change the this context of an already-bound function—it just returns the same pre-bound function you already had. That's why it still pulls the name property from the original Salutation instance.
How to fix this if you need to re-bind
If you want the flexibility to bind getGreeting to different contexts, you have two solid options:
Option 1: Remove the initial bind in the constructor
Delete the line this.getGreeting = this.getGreeting.bind(this) from the constructor. Now salutation.getGreeting refers to the original unbound prototype method, so you can bind it to any context you want:
let myName = { name: 'John' } class Salutation { constructor() { this.name = 'Mike'; // No bind here anymore } getGreeting() { return `Hi. My name is ${this.name}` } } const salutation = new Salutation(); const boundToMyName = salutation.getGreeting.bind(myName); boundToMyName(); // Logs "Hi. My name is John" const boundToSalutation = salutation.getGreeting.bind(salutation); boundToSalutation(); // Logs "Hi. My name is Mike"
Option 2: Use the prototype method directly for re-binding
If you need to keep the initial bind (e.g., to preserve context for event handlers), you can access the original unbound method from the class prototype and bind that instead:
let myName = { name: 'John' } class Salutation { constructor() { this.name = 'Mike'; this.getGreeting = this.getGreeting.bind(this) } getGreeting() { return `Hi. My name is ${this.name}` } } const salutation = new Salutation(); // Bind the prototype method (not the instance's bound version) const boundToMyName = Salutation.prototype.getGreeting.bind(myName); boundToMyName(); // Logs "Hi. My name is John" // The instance's bound method still works as intended salutation.getGreeting(); // Logs "Hi. My name is Mike"
内容的提问来源于stack exchange,提问作者Prem

