684 votos

¿Cuál es la mejor manera de definir una clase en JavaScript?

Yo prefiero utilizar la programación orientada a objetos en proyectos de gran escala como la que yo estoy trabajando ahora mismo. Necesito crear varias clases en JavaScript, pero, si no me equivoco, hay al menos un par de maneras de hacerlo. ¿Cuál sería la sintaxis y por qué se hace de ese modo?

O estoy muy lejos de la base aquí y sólo hay una manera de definir clases?

Me gustaría evitar el uso de las bibliotecas de terceros - al menos al principio.
¿Está buscando otras respuestas, me encontré con el artículo de la Programación Orientada a Objetos con JavaScript, Parte I: la Herencia - Doc JavaScript que analiza la programación orientada a objetos en JavaScript. ¿Hay una manera mejor de hacer la herencia?

739voto

Triptych Puntos 70247

Aquí está la manera de hacerlo sin usar librerías externas:

// Define a class like this
function Person(name, gender){

   // Add object properties like this
   this.name = name;
   this.gender = gender;
}

// Add methods like this.  All Person objects will be able to invoke this
Person.prototype.speak = function(){
    alert("Howdy, my name is" + this.name);
}

// Instantiate new objects with 'new'
var person = new Person("Bob", "M");

// Invoke methods like this
person.speak(); // alerts "Howdy, my name is Bob"

Ahora, la respuesta real es mucho más complejo que eso. Por ejemplo, no hay tal cosa como clases en JavaScript. JavaScript utiliza una prototype-de herencia basado en el esquema.

Además, hay numerosas bibliotecas populares de JavaScript que tienen su propio estilo de aproximación de clase-como la funcionalidad de JavaScript. Usted querrá echa un vistazo, al menos, Prototype y jQuery.

Decidir cual de estos es el "mejor" es una gran manera de comenzar una guerra santa en Stack Overflow. Si usted se está embarcando en una mayor JavaScript pesados proyecto, es definitivamente vale la pena el aprendizaje de una biblioteca popular y de hacerlo a su manera. Soy un Prototipo de hombre, pero de Stack Overflow parece inclinarse hacia jQuery.

Como cuanto hay de ser sólo "una forma de hacerlo", sin que las dependencias en las bibliotecas externas, la forma en que yo escribí es bastante mucho.

212voto

Jörg W Mittag Puntos 153275

La mejor manera de definir una clase en JavaScript es no definir una clase.

En serio.

Hay diferentes sabores de la orientación a objetos, algunos de ellos son:

  • basada en la clase OO (introducido por primera vez por Smalltalk)
  • basado en prototipos OO (introducido por primera vez por el Auto)
  • multimethod basado OO (introducido por primera vez por CommonLoops, creo)
  • predicado basado OO (ni idea)

Y probablemente los demás no sé.

JavaScript implementa prototipo basado en OO. En prototipo basado OO, se crean nuevos objetos copiando de otros objetos (en lugar de ser instanciado a partir de una plantilla de clase) y los métodos vivir directamente en los objetos, en lugar de en las clases. La herencia se realiza a través de la delegación: si un objeto no tiene un método o propiedad, se miró en su prototipo(s) (por ejemplo. el objeto fue clonado a partir de), entonces el prototipo de prototipos y así sucesivamente.

En otras palabras: no hay clases.

JavaScript en realidad tiene un buen tweak de ese modelo: constructores. No sólo permite la creación de objetos mediante la copia de los ya existentes, también se puede construir "out of thin air", por así decirlo. Si se llama a una función con el new de palabras clave, la función se convierte en constructor y el this de palabras clave no seleccione el objeto actual, pero en lugar de un recién creado "vacío". Así, usted puede configurar un objeto de la manera que desee. De esa manera, JavaScript constructores puede tomar uno de los papeles de clases tradicional basada en la clase OO: servir como una plantilla o un modelo para los nuevos objetos.

Ahora, JavaScript es un lenguaje muy poderoso, por lo que es muy fácil de implementar una clase basada OO sistema en JavaScript , si usted quiere. Sin embargo, sólo debe hacerlo si realmente tienen una necesidad y no sólo porque esa es la manera en que Java lo hace.

56voto

Daniel X Moore Puntos 6026

Yo prefiero usar Daniel X. Moore {SUPER: SYSTEM}. Esta es una disciplina que ofrece beneficios tales como verdaderas variables de instancia, rasgo basado en la herencia, jerarquías de clase y las opciones de configuración. El ejemplo siguiente ilustra el uso de las verdaderas variables de instancia, que creo que es la mayor ventaja. Si usted no necesita las variables de instancia y son felices sólo con público o privado de las variables, a continuación, probablemente hay sistemas más simples.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  return {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };
}

var fogel = Person({
  age: "old enough"
});
fogel.introduce(); // "Hi I'm McLovin and I'm old enough"

Wow, eso realmente no es muy útil por sí mismo, pero echa un vistazo a la adición de una subclase:

function Ninja(I) {
  I = I || {};

  Object.reverseMerge(I, {
    belt: "black"
  });

  // Ninja is a subclass of person
  return Object.extend(Person(I), {
    greetChallenger: function() {
      return "In all my " + I.age + " years as a ninja, I've never met a challenger as worthy as you...";
    }
  });
}

var resig = Ninja({name: "John Resig"});

resig.introduce(); // "Hi I'm John Resig and I'm 25"

Otra ventaja es la capacidad de disponer de los módulos y rasgo de la base de la herencia.

// The Bindable module
function Bindable() {

  var eventCallbacks = {};

  return {
    bind: function(event, callback) {
      eventCallbacks[event] = eventCallbacks[event] || [];

      eventCallbacks[event].push(callback);
    },

    trigger: function(event) {
      var callbacks = eventCallbacks[event];

      if(callbacks && callbacks.length) {
        var self = this;
        callbacks.forEach(function(callback) {
          callback(self);
        });
      }
    },
  };
}

Un ejemplo de la clase de persona incluir la enlazable módulo.

function Person(I) {
  I = I || {};

  Object.reverseMerge(I, {
    name: "McLovin",
    age: 25,
    homeState: "Hawaii"
  });

  var self = {
    introduce: function() {
      return "Hi I'm " + I.name + " and I'm " + I.age;
    }
  };

  // Including the Bindable module
  Object.extend(self, Bindable());

  return self;
}

var person = Person();
person.bind("eat", function() {
  alert(person.introduce() + " and I'm eating!");
});

person.trigger("eat"); // Blasts the alert!

Divulgación: soy Daniel X. Moore y este es mi {SUPER: SYSTEM}. Es la mejor forma de definir una clase en JavaScript.

41voto

liammclennan Puntos 3535
var Animal = function(options) {
    var name = options.name;
    var animal = {};

    animal.getName = function() {
        return name;
    };

    var somePrivateMethod = function() {

    };

    return animal;
};

// usage
var cat = Animal({name: 'tiger'});

24voto

Jarek Puntos 2092

Creo que usted debería leer Douglas Crockford del Prototípico de la Herencia en JavaScript y la Herencia Clásica en JavaScript.

Ejemplos de su página:

Function.prototype.method = function (name, func) {
    this.prototype[name] = func;
    return this;
};

Efecto? Esto le permitirá agregar métodos en forma más elegante:

function Parenizor(value) {
    this.setValue(value);
}

Parenizor.method('setValue', function (value) {
    this.value = value;
    return this;
});

También recomiendo sus videos: JavaScript Avanzado.

Usted puede encontrar más videos en su página: http://javascript.crockford.com/ En Juan Reisig libro usted puede encontrar muchos ejemplos de Douglas Crockfor del sitio web.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X