Classes de JavaScript

Definindo uma classe em JavaScript:

var Person = function(name, email) {
this.name = name;
this.email = email;

// 1 possible way to define a "composite property"
Object.defineProperty(this, "nameWithEmail", {
get: function() {
return this.name + " <" + this.email + ">";
}
});

// I think a simpler way might be to just use a function (see `toString`)
};

// things defined under prototype will be "shared/inheried" by all classes,
// as opposed to name and email for example
Person.prototype.sayHi = function() {
console
.log("Hello, my name is " + this.toString());
};

Person.prototype.toString = function() {
return this.name + " <" + this.email + ">";
};

Agora, podemos estender a classe Person:

// we define the object properties in the constructor function
var Employee = function(name, email, position) {
Person.call(this, name, email); // calling person constructor: something like super() in other languages
this.position = position;
};

// extend the Employee class with Person
Employee.prototype = Object.create(Person.prototype);

// override some functions
Employee.prototype.sayHi = function() {
Person.prototype.sayHi.call(this);
console
.log("I am a " + this.position);
};

Uma alternativa: com underscore.js

// instead of 
// Employee.prototype = Object.create(Person.prototype);
_
.extend(Employee.prototype, Person.prototype);

Com o underscore.js, também podemos fazer herança múltipla facilmente

_.extend(Employee.prototype, Person.prototype);
_
.extend(Employee.prototype, {
doSomething
: function() { ... }
});

Não parece fazer mais a cadeia de protótipos. No entanto, quando você console.log()cria os protótipos, parece que aquele com JS puro é mais limpo do que a versão de sublinhado (menos métodos extras, etc.). Eu postei uma pergunta no StackOverflow sobre isso.