6
\$\begingroup\$

Originally posted this here, and it was helpfully suggested to post in this forum.

In the past couple of years I've returned part time to programming after a 15 year gap. I was C/UNIX. So, I've picked up PHP, Java and C++ ok, but have struggled with JavaScript.

Finally I think I've found a way to 'create' classes that can inherit and wondered if anyone would care to comment. Here is an example:

<!doctype html>
<head>
 <title>Basic</title>
</head>
<body>
 <div id="d1"></div>
 <script type="text/javascript">
function Base( options ) {
 var that = this;
 options = options || {};
 Object.keys( options ).forEach( function( item ) {
 that[item] = options[item];
 });
}
function Creature( options ) {
 this.legs = 4;
 Base.call( this, options );
 console.log("New creature");
}
Creature.prototype.showNumberOfLegs = function() {
 console.log( "Number legs " + this.legs );
};
function Mammal( options ) {
 this.fur = true;
 Creature.call( this, options );
 console.log("New mammal");
}
Mammal.prototype = Object.create( Creature.prototype );
Mammal.prototype.showFur = function() {
 console.log( "Fur " + this.fur );
};
var c = new Creature();
c.showNumberOfLegs();
var m = new Mammal({ legs: 6, fur: false });
m.showNumberOfLegs();
m.showFur();
 </script>
</body>
</html>
asked Oct 4, 2015 at 15:20
\$\endgroup\$
0

1 Answer 1

11
\$\begingroup\$

but have struggled with JavaScript

Welcome to JavaScript, where all things look fine but are actually half broken. :D

Finally I think I've found a way to 'create' classes that can inherit

I think there's a saying that goes like "Composition over inheritance". That's because composition is more flexible and doesn't impose hard taxonomies of classes or make you resort to multiple inheritance. See this video for a detailed comparison.

Now let's go over to your code. Let's just say for now that I advocate inheritance. Let's do this!

options = options || {};
Object.keys( options ).forEach( function( item ) {
 that[item] = options[item];
});
// to
Object.keys(options || {}).forEach(function(key){
 this[key] = options[key];
}, this);
// to
Object.assign(this, options || {});

You can streamline your assignment operation by inlining the defaulting of options to an empty object. The context (this) can also be provided to the callback of forEach via its second argument.

If you can do ES6, there's Object.assign() which does the same thing in lesser code. It pretty much looks like jQuery's $.extend if you're familiar with it.


Base.call( this, options );
// to
Base.apply(this, arguments);

The reason is that you don't actually know how many arguments you'll potentially provide the constructor. In your code, you assume your only argument is options, but that might change. apply allows you to pass in an array or array-like object as an argument, spreading it as the arguments on the receiving end.


You are missing:

Creature.prototype = Object.create(Base.prototype);

Here's a checklist of what to do when doing prototypal inheritance manually:

  • Inherit the parent properties (Parent.apply(this, arguments).
  • Inherit the parent prototype (Child.prototype = Object.create(Parent.prototype))
  • Define child properties and their default values
  • Define child methods
answered Oct 4, 2015 at 17:47
\$\endgroup\$
5
  • 1
    \$\begingroup\$ It's good to remember that Object.keys() is only supported on IE9 and newer. If support for IE8 is required, you need a polyfill or an alternative method. \$\endgroup\$ Commented Oct 5, 2015 at 2:21
  • \$\begingroup\$ @IsmaelMiguel The OP did use forEach and Object.create, so maybe it's safe to say the code is for ES5-compatible browsers. \$\endgroup\$ Commented Oct 5, 2015 at 2:38
  • \$\begingroup\$ Oh, right... Maybe the O.P. may not be aware, since there's nothing saying that IE support isn't a requirement. Now-a-days, I don't even know the amount of bad advices that are around the internet \$\endgroup\$ Commented Oct 5, 2015 at 2:41
  • 1
    \$\begingroup\$ where all things look fine but are actually half broken. I'd argue it's the other way around; where all things look broken but are actually just fine. \$\endgroup\$ Commented Oct 5, 2015 at 2:59
  • \$\begingroup\$ Thanks @JosephtheDreamer, that's a great answer - very helpful. And the video - maybe even more helpful :) I'd just got to that problem with my Pet class ... I shall do some thinking \$\endgroup\$ Commented Oct 5, 2015 at 6:17

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.