Reputation: 4897
From my limited experience with OOP javascript, a common way to handle multiple objects with different properties but the same methods would be using a constructor as follow:
function Animal ( type ) {
this.type = type
};
Animal.prototype.sayHello = function () {
return 'Hi, I am a ' + this.type
};
var goat = new Animal( 'Goat' );
My understanding here is goat
would inherit / have a reference to the functions of Animal
.
I presume I can replicate the above with the following object literal notion:
var Animal = {
type : '',
sayHello : function () {
return 'Hi, I am a ' + this.type
}
}
var goat = Object.create( Animal );
goat.type = 'Goat';
Is the inheritance to Animal
lost here, or is Goat
still referencing Animal
for methods?
I would like to know if there are any issue using Object.create()
instead of new
to replicate a constructor / class. Is there a perf offset or any reason to carry on using new
?
Any advice would be appreciated, I am happy to add to the question if clarification is needed.
Updated Object Creation
var Animal = {
sayHello : function () {
return 'Hi, I am a ' + this.type
}
}
var goat = Object.create( Animal, { 'type' : { value: 'goat' } } );
Upvotes: 2
Views: 316
Reputation: 1074238
...a common way to handle multiple objects with different properties but the same methods would be using a constructor...
Yes, the other common way being (as you've seen) Object.create
.
My understanding here is
goat
would inherit / have a reference to the functions ofAnimal
.
Not quite. In the new Animal
expression, goat
gets assigned the object referenced by Animal.prototype
as its underlying prototype. There is no direct connection to Animal
, just to Animal.prototype
. (Animal.prototype
has a reference back to Animal
via its constructor
property, in the normal course of things, although that link can get broken if someone assigns a new object to Animal.prototype
.)
Is the inheritance to
Animal
lost here, or isGoat
still referencingAnimal
for methods?
In your non-constructor example, goat
gets Animal
as its underlying prototype, so for any property not found on goat
itself, the JavaScript engine will look at Animal
to see if it has it. In your example, that means that goat
is using sayHello
from Animal
, but not type
, because goat
has its own type
.
The rough equivalent of this:
function Animal ( type ) {
this.type = type
};
Animal.prototype.sayHello = function () {
return 'Hi, I am a ' + this.type
};
var goat = new Animal( 'Goat' );
...using Object.create
to set the prototype instead looks like this:
var animalPrototype = {
sayHello: function () {
return 'Hi, I am a ' + this.type
}
};
function createAnimal(type) {
var rv = Object.create(animalPrototype);
rv.type = type;
return rv;
};
var goat = createAnimal( 'Goat' );
Re your comment:
Would there be any issue including
animalPrototype
insidecreateAnimal
and then callingObject.create(this.animalPrototype)
?
If you mean this:
function createAnimal(type) {
var animalPrototype = { // Issue #1
sayHello: function () {
return 'Hi, I am a ' + this.type
}
};
var rv = Object.create(this.animalPrototype); // Issue #2
rv.type = type;
return rv;
};
var goat = createAnimal( 'Goat' );
...then yes, there are two issues:
animalPrototype
for each call to createAnimal
, which defeats the purpose, and 2. this
within the call to createAnimal
will either be the global object (loose mode) or undefined
(strict mode), so this.animalPrototype
probably isn't the expression you want.You could do this:
function createAnimal(type) {
var rv = Object.create(createAnimal.proto);
rv.type = type;
return rv;
};
createAnimal.proto = {
sayHello: function () {
return 'Hi, I am a ' + this.type
}
};
var goat = createAnimal( 'Goat' );
Could be confusing for people, of course, since that looks so much like a constructor function.
Upvotes: 6