3
\$\begingroup\$

https://github.com/exebook/dnaof

I created this simple inheritance tool for JavaScript, could any one with deep knowledge in JavaScript prototyped inheritance review it?

Here is the library itself:

kindof = function(K) {
    function X() {}
    if (K != undefined) X.prototype = new K
    X.can = X.prototype
    return X
}
dnaof = function(x, f) {
    var p = x.__proto__
    x.__proto__ = p.__proto__
    var r = p.__proto__[f].apply(x)
    x.__proto__ = p
    return r
}

And here is the example usage to demonstrate what it can do:

require('./dnaof')

// create a kind of idiot without ancestor:

var idiot = kindof()

// tell what it can do:

idiot.can.say = function() { return this.name + ' can chat' }
idiot.can.rest = function() { console.log('bzzzz.z.z.z... (' + this.name + ')') }

// a new kind of smart inherits from a kind of idiot

var smart = kindof(idiot)

// he can also say something:

smart.can.say = function() {
    // he can say something new, and he can say the same thing as an idiot can:
    return dnaof(this, 'say') + ', ' + this.name + ' can talk'
}

// a kind of a genious can do the same things as an idiot and smart can, and even more:

var genious = kindof(smart)
genious.can.say = function() {
    return dnaof(this, 'say') + ', ' + this.name + ' can discuss'
}

// instantiate three persons:

var bob = new idiot
var alice = new smart
var candy = new genious

// assign properties, because to make life simpler we do not initialize anything during creation:

bob.name = 'bob'
alice.name = 'alice'
candy.name = 'candy'

// let them talk:

console.log(bob.say())
console.log(alice.say())
console.log(candy.say())

// let them take some rest:

alice.rest(), bob.rest(), candy.rest()
\$\endgroup\$
3
  • 1
    \$\begingroup\$ Just a tip, __proto__ is non-standard. See here developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… \$\endgroup\$
    – elclanrs
    Mar 2, 2014 at 7:27
  • \$\begingroup\$ I know, but is there a better way? \$\endgroup\$
    – exebook
    Mar 2, 2014 at 7:44
  • \$\begingroup\$ Unfortunately, I would probably rewrite the whole library for something else, however here's a few hints. Rather than using new to setup the prototype chain, you can use Object.create in every modern browsers. Also, to dynamically get the parent class, you can do Object.getPrototypeOf(Object.getPrototypeOf(this)). With these changes you can stop using __proto__. Also, you should opt for a syntax that doesn't require you to write obj.can all the time to define new members. \$\endgroup\$
    – plalx
    Mar 9, 2014 at 6:09

1 Answer 1

2
\$\begingroup\$

From a once over, and borrowing from the comments:

  • __proto__ is bad news, MDN mentions this in a big red box of doom.
  • There is no means to pass parameters to the constructor, that does not make it simple
  • X, x, k, r and p are terrible variable names
  • dnaof is an unfortunate name
  • lowerCamelCase is good for you, kindof -> kindOf,
  • You can get the parent class thru Object.getPrototypeOf(Object.getPrototypeOf(this)) in dnaof
  • I have mixed feelings about the can trick. It is shorter than typing prototype, but it's also a candidate for nameclashes.
  • You have no comments at all in your code, combined with 1 letter variables that makes for not good code
  • If I were to build an OO library, I would also play with constructor and add some support for private.

All in all, this is something I would not mind using, but that I would hate to have to maintain.

\$\endgroup\$
1
  • \$\begingroup\$ Thanks for comments. Actually I switched completely from using "prototype", now 'dnaof' will store each function super-call in it self. \$\endgroup\$
    – exebook
    Mar 22, 2014 at 9:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.