Yes, it is that simple. In your example with Object.create/Object.assign
, you are using a factory function to create new instances of duck
(similar to the way jQuery creates new instances if you select an element with var body = $('body')
). An advantage of this code style is, that it doesn't force you to call a constructor of animal
when you want to create a new duck
instance (as opposed to ES2015 Classes).
Differences in initialization
Maybe one interesting tidbit that works slightly differently than if you were to use a constructor (or any other initialization function):
When you create a duck
instace, all the properties of animal
are in the [[Prototype]]
slot of the duck
instance.
var daffy = duck();
console.log(daffy); // Object { speak: function() }
So daffy
does not have any own x
and y
properties yet. However, when you call the following, they will be added:
daffy.move(6, 7);
console.log(daffy); // Object { speak: function(), x: 6, y: 7 }
Why? In the function-body of animal.move
, we have the following statement:
this.x = this.x + x;
So when you call this with daffy.move
, this
refers to daffy
. So it will try to assign this.x + x
to this.x
. Since this.x
is not yet defined, the [[Prototype]]
chain of daffy
is traversed down to animal
, where animal.x
is defined.
Thus in the first call, the this.x
on the right side of the assignment refers to animal.x
, because daffy.x
is not defined. The second time daffy.move(1,2)
is called, this.x
on the right side will be daffy.x
.
Alternative Syntax
Alternatively, you could also use Object.setPrototypeOf
instead of Object.create/Object.assign
(OLOO Style):
var duck = function () {
var duckObject = {
speak : function () {
console.log("quack");
return this;
}
};
return Object.setPrototypeOf(duckObject, animal);
}
Naming Conventions
I'm not aware of any established conventions. Kyle Simpson uses uppercase letters in OLOO, Eric Elliot seems to use lowercase. Personally I would stick with lower-case, because the object literals that act as constructors are already fully fledged objects themselves (not just blueprint, like classes would be).
Singleton
If you only wanted a single instance (e.g. for a singleton), you could just call it directly:
var duck = Object.assign(Object.create(animal), {
speak : function () {
console.log("quack");
return this;
}
});
duck.move(6, 7).locate().speak();