2015-04-22 4 views
3

Я пытаюсь создать объект javascript, который вычисляет различные значения для свойств, установленных на нем. Я составил этот простой пример того, что я пытаюсь достичь: JSFIDDLEСвойства объекта Javascript, рассчитанные (на лету) из других свойств объекта

var obj = {}; 
obj.a = 2; 
obj.b = 5; 
obj.avg = "(obj.a + obj.b)/2"; 
obj.rounded = "Math.floor(eval(obj.avg))"; 

console.log("rounded avg: " + eval(obj.rounded)); 
//simulate changing properties 
obj.a = Math.floor(Math.random() * 10); 
obj.b = Math.floor(Math.random() * 10); 
console.log("rounded avg: " + eval(obj.rounded)); 

Приведенный выше код в настоящее время добивается того, чего я хочу (используя стандартный набор значений, как «а» и «б» вычислить «среднюю» затем используя «avg» во втором вычислении «округлены»).

Есть ли лучший способ достичь этого (в идеале без вызовов eval() всякий раз, когда вычисленное свойство ссылается на другое свойство).

Я хотел бы, чтобы рассчитанные свойства действовали как функции (вычисляли их значение, когда они ссылаются), а не вычисляли их значение изначально и не меняли - я бы хотел, чтобы не использовать () для вызова функций (так что я могу ссылаться как на простые значения, так и на рассчитанные значения одинаково - просто по их имени свойства).

ответ

6

Вместо использования eval, использование выполняет следующие функции:

var obj = {}; 
 
obj.a = 2; 
 
obj.b = 5; 
 
obj.avg = function() { return (this.a + this.b)/2; }; 
 
obj.rounded = function() { return Math.floor(this.avg()); }; 
 

 
console.log("rounded avg: " + obj.rounded()); 
 
obj.a = Math.floor(Math.random() * 10); 
 
obj.b = Math.floor(Math.random() * 10); 
 
console.log("rounded avg: " + obj.rounded());

Если вы не должны поддерживать старые браузеры, чтобы избежать необходимости использовать круглые скобки при вызове функции, вы можете использовать getters следующим образом:

var obj = { 
 
    a: 2, 
 
    b: 5, 
 
    get avg() { return (this.a + this.b)/2; }, 
 
    get rounded() { return Math.floor(this.avg) } 
 
} 
 

 
console.log("rounded avg: " + obj.rounded); 
 
obj.a = Math.floor(Math.random() * 10); 
 
obj.b = Math.floor(Math.random() * 10); 
 
console.log("rounded avg: " + obj.rounded);

+2

Конечно, но ОП сказал: «Мне бы хотелось избежать использования() для вызова функций». –

+1

@torazaburo Я был «добираюсь» до этого :-) –

+1

@RobbyCornelissen Ha, теперь я * 'get' * it -" получение "... – Xufox

1

похоже, что вы находитесь за тем, что называется расчетным объектом. Это переменная, которая вычисляется при ее запросе. В JavaScript можно использовать Object Getter/Setter Syntax

+1

Первый раз, когда я прочитайте этот вопрос, я думал о вычисленных именах свойств ... 'obj = ({[propname]: 6})'. – Xufox

+0

@Xufox Почему парс вокруг объекта? –

+0

@torazaburo Иногда я получаю «_SyntaxError: missing; before statement_ "при записи объектов в консоль без назначения ... так что просто быть в безопасности ... – Xufox

6

Используйте Getters, если вам не нужно поддерживать Internet Explorer 8 или меньше:

var obj = { 
    a:2, 
    b:5, 
    get avg(){ 
    return (this.a + this.b)/2; 
    }, 
    get rounded(){ 
    return Math.floor(this.avg); 
    } 
} 

Использование:

obj.a; // returns 2 
obj.b; // returns 5 
obj.avg; // returns 3.5 
obj.rounded; // returns 3 
+0

Благодарим вас за ответ. Мне очень хотелось бы использовать синтаксис getter, но мне нужно поддерживать IE8. – JRulle

+0

@JRulle Весь мужчина, правда? Я действительно сожалею о вашей борьбе ... – Xufox

Смежные вопросы