Геттеры не работают в JavaScript
Я пытаюсь выяснить, что такое геттеры и сеттеры в JavaScript. Вот мой объект
function User(fullName) {
this.fullName = fullName;
Object.defineProperties(this,{
firstName :{
get: function(){
return this.fullName.split(" ")[0];
},
set :function(value){
this.firstName = value;
}
},
lastName:{
get: function(){
this.lastName = this.fullName.split(" ")[1];
},
set: function(value){
this.lastName = value;
}
},
fullName :{
set: function(value){
this.fullName = value;
}
}
});
}
Затем создает нового пользователя:
var user = new User("New User");
Но когда я пытаюсь получить свойство firstName, как
alert( user.firstName )
выдает ошибку "Не удается прочитать свойство split из undefined".
Что может вызвать проблему? Похоже, что 'this' не видно внутри функции get, но, насколько я понимаю, должно. Спасибо!
3 ответа
Вам не нужен сеттер для fullName
как прямое назначение будет работать.
function User(fullName) {
this.fullName = fullName || '';
Object.defineProperties(this, {
firstName: {
get: function() {
return this.fullName.split(" ")[0];
},
set: function(value) {
this.firstName = value; // NOTE: This will throw an error
}
},
lastName: {
get: function() {
return this.fullName.split(" ")[1];
},
set: function(value) {
this.lastName = value; // NOTE: This will throw an error
}
}
});
}
var joe = new User('John Doe');
var jane = new User('Jane Dane');
jane.fullName = 'Jane Doe';
document.write(
'<pre>' + joe.firstName + '</pre>' +
'<pre>' + jane.lastName + '</pre>'
);
Однако, как отмечено в комментариях к коду выше, вы не можете установить свойство на this
с тем же именем, что и определенное свойство с установщиком. Например:
// defining `firstName`
firstName: {
...
set: function(value) {
this.firstName = value; // NOTE: This will throw an error
}
Эта операция вызовет ошибку стека рекурсии, поскольку она будет постоянно пытаться обновить firstName
поскольку this.firstName
это сеттер.
Чтобы избежать этого, вы можете использовать локальные переменные в функции-конструкторе и сделать что-то вроде:
function User(fullName) {
var firstName;
var lastName;
Object.defineProperties(this, {
firstName: {
get: function() {
return firstName;
},
set: function(value) {
return (firstName = value);
}
},
lastName: {
get: function() {
return lastName;
},
set: function(value) {
return (lastName = value);
}
},
fullName: {
get: function() {
return firstName + ' ' + lastName;
},
set: function(value) {
var names = value && value.split(' ');
firstName = names[0];
lastName = names[1];
}
}
});
if (fullName) {
this.fullName = fullName;
}
}
var joe = new User('John Doe');
var jane = new User('Jane Dane');
jane.lastName = 'Doe';
document.write(
'<pre>' + joe.firstName + '</pre>' +
'<pre>' + jane.lastName + '</pre>'
);
Некоторые проблемы / изменения, необходимые для вашего кода:
- this.fullName.split ("") [0]; => попытается вызвать getFullName, поскольку fullName определено как свойство. Поскольку вы не определили getFullName, это приводит к ошибке
Скажем, вы идете вперед и определяете геттер для fullName:
get: function () {return this.fullName; }
Это создаст стекопоток, так как this.fullName заканчивается рекурсивным вызовом getFullName()
Правильный способ его использования (конечно, обновите сеттеры, чтобы сделать что-то полезное):
function User(fullName) {
this.fullName = fullName;
Object.defineProperties(this, {
firstName: {
get: function () {
return this.fullName.split(" ")[0];
},
set: function (value) {
this.firstName = value;
}
},
lastName: {
get: function () {
return this.fullName.split(" ")[1];
},
set: function (value) {
this.lastName = value;
}
}
});
}
var user = new User("New User");
alert( user.firstName );
У fullName нет получателя, поэтому он возвращает неопределенный
получить
Функция, которая служит геттером для свойства, или неопределенная, если нет геттера. Функция return будет использоваться в качестве значения свойства.
По умолчанию не определено.