не удается привязаться к новой функции конструктора

#javascript #this

Вопрос:

следующий код выдаст ошибку типа для свойства name: Не удается назначить только для чтения свойство » имя » функции.
Я ожидаю получить имя пользователя «Неизвестно». Я получаю этот результат, если использую привязку, например:

 const User = function(name) {
  this.name = name
}

function userMsg(msg) {
  this.name = this.name || 'Unknown'
  return `${this.name} said: ${msg}`
}

const newMsg = userMsg.bind(User)
newMsg('say smth') 

Комментарии:

1. Это похоже на проблему XY. Почему вы пытаетесь привязаться к функции конструктора? Конструктор не должен иметь name свойства, он должен присваиваться экземпляру User , когда он вызывается для создания экземпляра (чего вы никогда не делаете).

Ответ №1:

Ваш текущий код пытается использовать функцию User конструктора, как this внутри userMsg . Это вызывает проблему, которую вы выполняете userMsg в контексте а function . Функции имеют свойство только для чтения name , которое вы не можете перезаписать, которое происходит из Function.prototype.name .

К счастью, это все равно не то, что вы хотите делать. Если вы вместо привязки User функции свяжете экземпляр, созданный путем вызова функции конструктора, вы можете придерживаться своего свойства name :

 const User = function(name) {
  this.name = name
}

function userMsg(msg) {
  this.name = this.name || 'Unknown'
  return `${this.name} said: ${msg}`
}

const max = new User('Max'); // you need a User instance to bind to
const newMsg = userMsg.bind(max); // bind it here

console.log(newMsg('say smth')); 

При фактическом использовании вы, вероятно , также не захотите использовать bind , а скорее добавите userMsg в User.prototype :

 const User = function(name) {
  this.name = name
}

User.prototype.userMsg = function(msg) {
  return `${this.name} says: ${msg}`
}

const max = new User('Max');
const newMsg = max.userMsg('Hello!'); // now we can call the function on the user

console.log(newMsg); 

или, по крайней мере, не bind делайте это постоянно, а скорее используйте call для использования пользовательского контекста один раз:

 const User = function(name) {
  this.name = name
}

function userMsg(msg) {
  this.name = this.name || 'Unknown'
  return `${this.name} said: ${msg}`
}

const max = new User('Max');
const newMsg = userMsg.call(max, 'say smth'); // use call to set context only for this call

console.log(newMsg);