Create a model (POJO) in JavaScript

10,051

Well, the comparator function you pass to sort() needs to take two arguments, so it can't be an instance method. I'd suggest you define it as a "static" method:

function person(name, age, gender) {
    this.name = name;
    this.age = age;
    this.gender = gender;
}

person.compare = function(personA, personB) {
    if(personA.name > personB.name) return 1;
    if(personA.name < personB.name) return -1;
    return personB.age - personA.age;
}

And then you can call it when you sort:

personalities.sort(person.compare);

I hope I understood correctly what you were asking.

Share:
10,051
Jean J. Michel
Author by

Jean J. Michel

More at about.me/jeanjmichel

Updated on June 13, 2022

Comments

  • Jean J. Michel
    Jean J. Michel almost 2 years

    can you help me with a doubt?

    I'm trying an approach more didatical in JS, creatind a POJO/POCO for a model class.

    I have a Person object:

    function person(name, age, gender) {
          this.name = name;
          this.age = age;
          this.gender = gender;
          return this;
    }
    

    Now I can create some data:

    var personalities = new Array(new person("Alicia", 152, "F"), 
                                  new person("Bartolomeu Simpson", 36, "M"),
                                  new person("Ayrton Senna", 58, "M"),
                                  new person("Jean J. Michel", 36, "M"),
                                  new person("Jean J. Michel", 37, "M"));
    

    Well, done it if I call sort method there is no action to order this data:

    personalities.sort();
    
    for(var i = 0; i < personalities.length; i++)
      console.log(personalities[i].name);
    

    Output is:

    Alicia
    Bartolomeu Simpson
    Ayrton Senna
    Jean J. Michel
    Jean J. Michel
    

    I created a toString() method:

    function person(name, age, gender) {
      this.name = name;
      this.age = age;
      this.gender = gender;
    
      this.toString = function() {
        return this.name + " " + 
               this.age + " years old" + 
               (this.gender == 'M' ? " man" : " woman");
      };
    
      return this;
    }
    

    Now the sort method is "ok", the output now is:

    Alicia
    Ayrton Senna
    Bartolomeu Simpson
    Jean J. Michel
    Jean J. Michel
    

    But I want do something different, order by name and age (oldest first). I implemented the method compareTo(obj):

    function person(name, age, gender) {
      this.name = name;
      this.age = age;
      this.gender = gender;
    
      this.toString = function() {
        return this.name + " " + 
               this.age + " years old" + 
               (this.gender == 'M' ? " man" : " woman");
      };
    
      this.compareTo = function(otherPerson) {
        var resultOfComparison = 0;
    
        if(this.name > otherPerson.name) {
          resultOfComparison = 1;
          return resultOfComparison;
        }
        else if(this.name < otherPerson.name) {
          resultOfComparison = -1;
          return resultOfComparison;
        }
        else if(this.age > otherPerson.age) {
          resultOfComparison = -1;
          return resultOfComparison;
        }
        else if(this.age < otherPerson.age) {
          resultOfComparison = 1;
          return resultOfComparison;
        }
    
        return resultOfComparison;
      };
    
      return this;
    }
    

    The method is ok, look it:

    var jean1 = new person("Jean J. Michel", 36, "M");
    var jean2 = new person("Jean J. Michel", 37, "M");
    
    console.log(jean1.compareTo(jean2)); //1
    console.log(jean1.compareTo(jean1)); //0
    console.log(jean2.compareTo(jean1)); //-1
    

    Can I use this approach to sort my array? Something like this:

    personalities.sort(person.compareTo);
    

    I really do not want to do it in a service class that use my model:

    personalities.sort(function(personA, personB) {
                         var resultOfComparison = 0;
    
                         if(personA.name > personB.name) {
                           resultOfComparison = 1;
                           return resultOfComparison;
                         }
                         else if(personA.name < personB.name) {
                           resultOfComparison = -1;
                           return resultOfComparison;
                         }
                         else if(personA.age > personB.age) {
                           resultOfComparison = -1;
                           return resultOfComparison;
                         }
                         else if(personA.age < personB.age) {
                           resultOfComparison = 1;
                           return resultOfComparison;
                         }
    
                         return resultOfComparison;
                       });
    

    I think that this is a model responsibility.

    Thanks for all help.

  • Jean J. Michel
    Jean J. Michel about 6 years
    Imagine a .js file servicePerson. I call this to list persons by name. The service call personDAO that goes to DB and populate an array with objects of type personModel.js (where is my function person). If I want to order de array in Service layer, have I call persons.sort(<and pass all compare logical logical here>)? It smells bad! This logical has to be in Model layer and be universal to all DAO, service, controller, etc.
  • Máté Safranka
    Máté Safranka about 6 years
    No, that's the point of what I wrote. You definitely shouldn't pass the sorting logic as an anonymous function to sort(). Instead, define it somewhere, e.g. as a static member function of your model class, and pass that function to sort().
  • Jean J. Michel
    Jean J. Michel about 6 years
    Sorry, now I wrote the code and understood your point. But I don't understand why this works :) person.compareTo = function ... why it is adding a function on my object? I can refctoring my person function now and change toString to person.toString = function... ;)
  • Máté Safranka
    Máté Safranka about 6 years
    person.compareTo is a "static method" of your person class. Strictly speaking, it's a method of your person() function. What this means is that you don't invoke it through instances of person, e.g. personA.compareTo (you'll actually get an error if you try to do this). Instead it's a method of the class itself. The whole topic goes a lot deeper, I'd recommend reading up on OOP in JavaScript to get a clearer picture. MDN has pretty good materials: developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects