

Show HN: Classes for javascript that you'd actually use - jayferd
http://github.com/jayferd/pjs

======
jarek-foksa
Please, please read [http://killdream.github.com/blog/2011/10/understanding-
javas...](http://killdream.github.com/blog/2011/10/understanding-javascript-
oop/)

Prototypical inheritance as of ES5 is really not that hard. Here is the same
example rewritten with prototypes: <https://gist.github.com/1558929>

~~~
mattmanser
Please, please realise most of us are not going to be able to use Object in
ES5 till IE8 dies.

~~~
mixu
Well, how about this? I'm fairly certain it's ES 3 compatible.

<https://gist.github.com/1559933>

The original was 28 lines, this is 36 (mostly because I like white space).

I haven't ever really tried to emulate classes in JS, but this is probably how
I would do it. The major difference is that this is written plain old
Javascript rather than some special syntax - easier to understand.

~~~
bmuon
Foo.prototype = new Bar() has the problem of setting the superclass' instance
properties as prototype properties of the subclass. This can be solved pretty
easily with something like Object.create (the first part explained here
<http://news.ycombinator.com/item?id=3424156>). Here's a different example in
30 lines: <https://gist.github.com/1032636>

------
mathrawka
It seems that everyone wants to add classes to Javascript. I understand that
prototype-based programming is a bit of a change from class-based programming,
but this is starting to feel like wasted energy on a problem that does not
need solving.

What benefits do developers get from using a 3rd-party library to create
classes in a prototype-based OOP language? Why can't developers just learn
that there is more than one style of OOP, and go with the flow?

~~~
wvenable
Because, for many things one wants to accomplish, prototype-based programming
is so verbose and error-prone. Adding a simple class-based abstraction over
top (which doesn't hide the prototype features) gives you the best of both
worlds.

------
ricardobeat
Pretty nice. Ends up being similar in structure to classes in coffeescript.

The very last lines worry me a bit though:

    
    
        // instantiate objects by calling the class
        MyClass() // => init!
    
        // allocate blank objects with `new`
        new MyClass // nothing logged
    

Having `MyClass()` and `new MyClass` behave differently is totally unwarranted
and will cause lots of confusion.

~~~
jayferd
Yeah, I'll admit that's a bit confusing. I did want to provide a way do
something like Object.create in environments where it's not available. This
way you can do `MySubclass.prototype = new MyClass` and not have to worry
about the initializer.

~~~
jayferd
(apologies for the double post)

Doing away with `new` in this way also has the added advantage of allowing
people to create objects with varargs, which is impossible otherwise.

~~~
ricardobeat

        new MyClass('bacon', 'eggs')
    

is perfectly possible, or am I misunderstanding your sentence?

How about exposing creation via `P.create`, `P.inherit` or something like it?

~~~
jayferd
right, but say you had an `var array = ['bacon', 'eggs']`. You can call a
function with these arguments with `fn.apply(null, array)` (yeah it's ugly but
it's how it's done in JS). This doesn't work with the `new` keyword.

EDIT: also, a class method would hurt your script's minifier performance.
...and at that point you may as well just call the function anyways :)

------
bmuon
Pjs may work for a small number of objects, but if you're dealing with a large
number of intances from a single class Pjs is going to use much more memory
than needed. That's because the recommended method P(function () { this.method
= fn; }) is declaring all methods as instances properties instead of using the
prototype, so all methods are actually new functions in new own properties
instead of properties of a shared object (the prototype).

~~~
jayferd
I should have mentioned it in the README, but if you read carefully, the
function you pass to P() is only called once, and you're adding functions to
the prototype. So it's actually pretty memory-efficient.

~~~
bmuon
Very interesting! I'll re-read the code.

------
ale55andro
normally all you'd need is a 2 liner utility method to facilitate inheritance.
For the rest you can use js as it is with it's actual language features which
maybe a little verbose (my only lament so far) and prototypical based but you
will begin to appreciate it in the long run. I don't like the exaggerated
syntactic sugar that many libs bring in, that try to abstract and tuck away js
as it is, making it pretend to be a class based language when it is not. That
said, this particular lib's size and the direct problems it tries to solves
are done so elegantly. It's hard to ignore the good job the author has done!

------
kibibyte
What are the differences between this and something like MooTools? What
benefits does P.js offer?

(Note: I was only introduced to MooTools today, so I have limited knowledge
about it.)

~~~
Flam
Mootools does all kinds of stuff. This just allows you to create classes in a
traditional way with inheritance and super afaik

------
limeblack
pjs certainly deserves props for being creative with the function passing, and
variable context. I haven't seen that exact usage before.

It seems every couple weeks javascript class library named X is released,
avoiding issue Y, and implementing fuctionality Z.

Using `prototype` isn't terribly far off from the class systems people keep
creating, so I can pretty much assume a single class library is going to reach
deep adoption anytime soon.

------
leeoniya
been using this one recently: <https://github.com/ded/klass>

------
aurynn
I'd use this. Does it work with node.js?

~~~
benatkin
Yes it does. <http://search.npmjs.org/#/pjs>

