Обычно вам нужны класс методы.Ответ @Raynos от 7 мая 2011 года завершает работу, но он определяет метод instance , а не метод класса.
Следующее иллюстрирует определение класса, где getter и setter являются частью класса.Это определение во многом похоже на ответ @Raynos, но с двумя отличиями в коде: (1) Действие defineProperties () было удалено из конструктора.(2) Аргумент "defineProperties ()", который был изменен с объекта экземпляра "this", на объект-прототип конструктора.
function TheConstructor(side) {
this.side = side;
}
Object.defineProperties(TheConstructor.prototype, {
area: {
get: function() { return this.side * this.side; }
,set: function(val) { this.side = Math.sqrt(val); }
}
});
// Test code:
var anInstance = new TheConstructor(2);
console.log("initial Area:"+anInstance.area);
anInstance.area = 9;
console.log("modified Area:"+anInstance.area);
, который приводит к следующим результатам:
initial Area:4
modified Area:9
Хотя обычно различие между классом и определением экземпляра - это просто вопрос стиля, есть смысл в хорошем стиле, и есть случай, когда различие имеет значение: запоминаемый получатель .Цель для записанного получателя описана здесь: Умные / перезаписываемые / ленивые получатели
Определите получатель на уровне класса, когда записанное значение должно относиться ко всему классу.Например, файл конфигурации должен быть прочитан только один раз;результирующие значения должны применяться в течение всей программы.В следующем примере кода определяется запомненный геттер на уровне класса.
function configureMe() {
return 42;
}
Object.defineProperties(TheConstructor.prototype, {
memoizedConfigParam: {
get: function() {
delete TheConstructor.prototype.memoizedConfigParam;
return TheConstructor.prototype.memoizedConfigParam = configureMe();
}
,configurable: true
}
});
// Test code:
console.log("memoizedConfigParam:"+anInstance.memoizedConfigParam);
Производит:
memoizedConfigParam:42
Как видно из примера, запомненные геттеры имеют характеристику функции геттера.удаляет себя, а затем заменяет себя простым значением, которое (предположительно) никогда не изменится.Обратите внимание, что для параметра «настраиваемый» должно быть установлено значение «истина».
Определите метод получения на уровне экземпляра, когда запомненное значение зависит от содержимого экземпляра.Определение перемещается внутри конструктора, и объектом внимания является «this».
function TheConstructorI(side) {
this.side = side;
Object.defineProperties(this, {
memoizedCalculation: {
get: function() {
delete this.memoizedCalculation;
return this.memoizedCalculation = this.expensiveOperation();
}
,configurable: true
}
});
}
TheConstructorI.prototype.expensiveOperation = function() {
return this.side * this.side * this.side;
}
//Test code:
var instance2 = new TheConstructorI(2);
var instance3 = new TheConstructorI(3);
console.log("memoizedCalculation 2:"+instance2.memoizedCalculation);
console.log("memoizedCalculation 3:"+instance3.memoizedCalculation);
Производит:
memoizedCalculation 2:8
memoizedCalculation 3:27
Если вы хотите гарантировать (а не предполагать), что запомненныйзначение никогда не изменится, атрибут «доступный для записи» необходимо изменить.Это делает код немного более сложным.
function TheConstructorJ(side) {
this.side = side;
Object.defineProperties(this, {
memoizedCalculation: {
get: function() {
delete this.memoizedCalculation;
Object.defineProperty( this, 'memoizedCalculation'
,{ value : this.expensiveOperation()
,writable : false
});
return this.memoizedCalculation;
}
,configurable: true
}
});
}
TheConstructorJ.prototype.expensiveOperation = function() {
return this.side * this.side * this.side;
}
//Test code:
var instanceJ = new TheConstructorJ(2);
console.log("memoizedCalculation:"+instanceJ.memoizedCalculation);
instanceJ.memoizedCalculation = 42; // results in error
Производит:
memoizedCalculation:8
>Uncaught TypeError: Cannot assign to read only property 'memoizedCalculation' of object '#<TheConstructorJ>'
В оригинальном вопросе OP от 7 марта 2011 г. представлен базовый синтаксис получения и установки, отметив, что онработал над объектом, но не над этим, и спрашивал, как определить методы получения и установки в конструкторе.В дополнение ко всем приведенным выше примерам существует также «дешевый» способ сделать это: создать новый объект в конструкторе, как это сделал OP, но затем назначить объект в качестве члена внутри «this».Итак, оригинальный код будет выглядеть так:
var MyClass = function(value) {
var test = !!value; // 'test' has to be a boolean
this.data = {
get test() { return test },
set test(value) { test = !!value }
};
};
var instance = new MyClass(true);
// But now 'data' is part of the access path
instance.data.test = 0;
console.log(instance.data.test);
Производит:
false
Верьте или нет, я фактически столкнулся с ситуациями, когда этот "дешевый выстрел" являетсялучшее решение.В частности, я использовал эту технику, когда у меня были записи из нескольких таблиц, инкапсулированных в одном классе, и я хотел представить унифицированное представление, как если бы они были единой записью, называемой «data».
Fun.
IAM_AL_X