The first version returns a simple Object, the second one creates a new Animal.
The first version is good for small data objects. They can store different values, and that's pretty much it. They don't need a lot of memory.
The second one is for bigger objects. You can attach prototypes to them and use the "this" keyword to reach the object's properties. Because every object has the same properties, they take up considerably more space, than the first method.
Let's take the following and create a vector object. With the first method, you would do something like this:
function createVector(x, y) {
return {
x: x,
y: y
};
}
//Add to vectors together
function add(vec1, vec2) {
return {x: vec1.x + vec2.x, y: vec1.y + vec2.y};
}
add(createVector(1, 1), createVector(1, 2)); //return {x: 2, y: 3}
This can be pretty useful, but what if you want to have multiple types of vectors (3 dimensional, 4 dimensional, etc...)? You would need to give a separate name for the adder functions, wich is not very nice. This is where the second method comes in. It can separate functions into different namespaces:
function Vector2(x, y) {
this.x = x;
this.y = y;
}
//Add vectors together:
Vector2.prototype.add = function(vec) {
this.x += vec.x;
this.y += vec.y;
};
new Vector2(1, 1).add(new Vector2(1, 2)); //{x: x, y: y}
This way, you can create multiple vector types and each of them could have a separate add function without interfering with each other.
You should use both of them based on what you want to achieve.