#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);