Skip to content
This repository


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Classes for javascript that don't suck.

branch: packaging

This branch is 0 commits ahead and 5 commits behind master

Fetching latest commit…

Cannot retrieve the latest commit at this time


P.js is a lightweight layer over javascript's built-in inheritance system that keeps all the good stuff and hides all the crap.

just show me some code already


// adapted from
// P.js exposes the `P` variable
var Animal = P(function(animal) {
  animal.init = function(name) { = name; };

  animal.move = function(meters) {
    console.log(" moved "+meters+"m.");

var Snake = P(Animal, function(snake, animal) {
  snake.move = function() {
    console.log("Slithering...");, 5);

var Horse = P(Animal, function(horse, animal) {
  horse.move = function() {
    console.log("Galloping...");, 45);

var sam = Snake("Sammy the Python")
  , tom = Horse("Tommy the Palomino")


how is pjs different from X

Most class systems for JS let you define classes by passing an object. P.js lets you pass a function instead, which allows you to closure private methods and macros. It's also <500b minified.

why doesn't pjs suck?

Unlike some other frameworks out there, Pjs doesn't do any of this:

  • mixins, interfaces, abstract static factory factories, and other bloat
  • use Object.create (it even works in IE < 8!)
  • break instanceof
  • hack functions onto this at runtime
  • rely on magical object keys which don't minify (the only special name is init)

what can i do with pjs?

  • inheritable constructors (via the optional init method)
  • closure-based "private" methods (see below)
  • easily call super on public methods without any dirty hacks
  • instantiate your objects without calling the constructor (absolutely necessary for inheritance)
  • construct objects with variable arguments

how do i use pjs?

You can call P in a few different ways:

// this defines a class that inherits directly from Object.
P(function(proto, super, class, superclass) {
  // define private methods as regular functions that take
  // `self` (or `me`, or `it`, or anything you really want)
  function myPrivateMethod(self, arg1, arg2) {
    // ...

  proto.init = function() {
    myPrivateMethod(this, 1, 2)

  // you can also return an object from this function, which will
  // be merged into the prototype.
  return { thing: 3 };

// this defines a class that inherits from MySuperclass
P(MySuperclass, function(proto, super, class, superclass) {
  proto.init = function() {
    // call superclass methods with, ...)
    //                           or super.method.apply(this, arguments);

// for shorthand, you can pass an object in lieu of the function argument,
// but you lose the niceness of super and private methods.
Limbo({ init: function(a) { this.thing = a } });

MyClass = P(function(p) { p.init = function() { console.log("init!") }; });
// instantiate objects by calling the class
MyClass() // => init!

// allocate blank objects with `new`
new MyClass // nothing logged
Something went wrong with that request. Please try again.