2015-10-24 4 views
0

Я работаю над функцией конструктора Person, которая принимает имя и возраст в качестве своих параметров и пытается реализовать метод, который извлекает все текущие значения и выходы текущего экземпляра Person среднее. Вот мой код ...Извлечение значения, хранящегося во всех экземплярах объекта

var Person = (function() { 
    //private state 
    var inst = 1; 

    function Person(name, age) { 
      this.name = name; 
      this.age = age; 
      Object.defineProperty(this, "age", { 
       get: function() { 
        return age; 
       }, 
       set: function(num) { 
        age = num; 
       } 
      }); 
      Object.defineProperty(this, "_id", { 
       value: inst++ 
      }); 
     } 

    //Attempt to return number of instances divided by all current Person weights 
    Person.prototype.aveAge = function() { 

     return inst; 
    }; 
    return Person; 
}()); 

var jim = new Person("jim", 32); 
var richard = new Person("richard", 27); 
richard.age = 28; 
var alfie = new Person("alfie", 42); 
Person.aveAge() //Returns TypeError: Person.aveAge is not a function 

Я создал переменную, которая используется во всех случаях (внутр), что увеличивает каждый раз, когда создается другой экземпляр и присваивает уникальный идентификатор. Я не могу понять, как я могу получить каждое «возрастное» значение всех существующих экземпляров Person, используя прототип aveAge, который я добавил внизу. Я также получаю «TypeError: Person.aveAge не функция», когда я пытаюсь вызвать его, даже чтобы проверить, что переменная «inst» содержит правильное количество экземпляров. Кто-нибудь знает, где я ошибаюсь?

+1

Прежде всего, 'Person.aveAge()' не на прототипе, но на самом конструкторе, так что 'Person.prototype.aveAge =' должен быть 'Person.aveAge = '. Во-вторых, ваше использование get/set не является необходимым и затеняет реквизит, который вы устанавливаете вручную. –

+0

'aveAge()' - это метод ваших объектов Person, например 'jim.aveAge()'. – jfriend00

+0

Наверное, больше нравится -> ** http: //jsfiddle.net/apgk6mhL/** – adeneo

ответ

1

Чувствуется странным, что удержать возраст от человека, когда он обращается к людям. Обратите внимание, что висящие вещи на __proto__ делают их доступными из конструктора (Person), а зависание на prototype делает их доступными из экземпляра (richard). Если Age обновлен, это нужно сделать с помощью setAge, чтобы PeopleTracker знал, что обновляет его память. Кроме того, в моем примере среднее вычисляется только тогда, когда это необходимо, а не каждый раз, когда человек хочет знать, что есть.

 var peopleTracker = { 
 
      _count: 0, 
 
      _ages: [], 
 
      averageAge: 0, 
 
      addPerson: function (age) { 
 
       var pt = peopleTracker; 
 

 
       pt._count += 1; 
 
       pt._ages.push(age); 
 
       pt.getAverage(); 
 
      }, 
 
      getAverage: function() { 
 
       var sum = 0, 
 
        pt = peopleTracker; 
 

 
       sum = pt._ages.reduce(function (a, b) { 
 
        return a + b; 
 
       }); 
 

 
       pt.averageAge = Math.round(sum/pt._count); 
 
      }, 
 
      update: function (oldAge, newAge) { 
 
       var pt = peopleTracker, 
 
        ages = pt._ages, 
 
        i = ages.indexOf(oldAge); 
 

 
       ages.splice(i, 1, newAge); 
 
       pt.getAverage(); 
 
      } 
 
     }; 
 

 
     var Person = function (name, age) { 
 
      this.name = name; 
 
      this.age = age; 
 
      peopleTracker.addPerson(age); 
 
     }; 
 

 
     Person.__proto__ = { // available from the constructor 
 
      Constructor: Person, 
 
      setAge: function (age) { 
 
       var oldAge = this.age; 
 
       this.age = age; 
 
       peopleTracker.update(oldAge, age); 
 
      }, 
 
      aveAge: function() { 
 
       return peopleTracker.averageAge; 
 
      } 
 
     }; 
 

 
     Person.prototype = Person.__proto__; // now also available from the instance 
 

 
     var jim = new Person("Jim", 32), 
 
      richard = new Person("Richard", 27), 
 
      alfie = new Person("Alfie", 42); 
 

 
     Person.aveAge(); // 34 
 
     richard.aveAge(); // 34 
 
     richard.setAge(20); 
 
     Person.aveAge(); // 31 
 
     richard.aveAge(); // 31