The problem of the printPerson approach is when you need "polymorphism"; i.e. you want to print an object but you don't want to know what kind of object it is: suppose
function newPerson(firstName, lastName) {
return { firstName: firstName,
lastName: lastName };
}
function newPet(name, kind) {
return { name: name,
kind: kind };
}
function printPerson(person) {
console.log(person.firstName + " " + person.lastName);
}
function printPet(pet) {
console.log(pet.name + " (a nice " + pet.kind + ")");
}
var p1 = newPerson("Andrea", "Griffini");
var p2 = newPet("Tobi", "cat");
printPerson(p1);
printPet(p2);
the problem however is... suppose you're given an object x and you need to print it, but you don't know if it's a person or a pet... how do you do?
Solution 1 is checking with if/then
if (x.firstName) {
printPerson(x);
} else {
printPet(x);
}
but this is annoying because if you add later another type of object you need to fix that.
The OOP solution is to change the code slightly
function Person(firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
this.print = function() {
console.log(this.firstName + " " + this.lastName);
};
}
function Pet(name, kind) {
this.name = name;
this.kind = kind;
this.print = function() {
console.log(this.name + " (a nice " + this.kind + ")");
};
}
and now the use becomes
var p1 = new Person("Andrea", "Griffini");
var p2 = new Pet("Tobi", "cat");
p1.print();
p2.print();
and the problem for a general x is just x.print().
Basically the idea is to keep the data (e.g. firstName, lastName) and the code (e.g. the implementation of print) together for each type of object.
You can add a new object type by just implementing the constructor and without the need to change other code that will "magically" end up calling the correct version of print.
Object.prototypemethod or useObject.create(which is "complicated"), there's no way around it.