2008-09-17 11 views
69

Utilizo la función jquery extend para extender un prototipo de clase.¿Existe alguna forma mejor de crear una clase orientada a objetos con jquery?

Por ejemplo:

MyWidget = function(name_var) { 
    this.init(name_var); 
} 

$.extend(MyWidget.prototype, { 
    // object variables 
    widget_name: '', 

    init: function(widget_name) { 
    // do initialization here 
    this.widget_name = widget_name; 
    }, 

    doSomething: function() { 
    // an example object method 
    alert('my name is '+this.widget_name); 
    } 
}); 


// example of using the class built above 
var widget1 = new MyWidget('widget one'); 
widget1.doSomething(); 

¿Hay una mejor manera de hacer esto? ¿Existe alguna manera más clara de crear la clase anterior con solo una declaración en lugar de dos?

Respuesta

50

Me gusta bastante el Simple JavaScript Inheritance de John Resig.

var MyWidget = Class.extend({ 
    init: function(widget_name){ 
    this.widget_name = widget_name; 
    }, 

    doSomething: function() { 
    alert('my name is ' + this.widget_name); 
    } 
}); 

NB: El objeto "clase" se demostró anteriormente no se incluye en sí mismo jQuery - es un fragmento de 25 línea desde el mismo Sr. jQuery, previsto en el artículo anterior.

+4

Ahh. Creo que debería haber leído el artículo _todo_ primero. Esta es una solución limpia, aunque requiere un código de configuración adicional. – Devon

15

Para resumir lo que he aprendido hasta ahora:

Aquí es la función de base que hace Class.extend() trabajar en jQuery (Copiado de Simple JavaScript Inheritance por John Resig):

// Inspired by base2 and Prototype 
(function(){ 
    var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; 

    // The base Class implementation (does nothing) 
    this.Class = function(){}; 

    // Create a new Class that inherits from this class 
    Class.extend = function(prop) { 
    var _super = this.prototype; 

    // Instantiate a base class (but only create the instance, 
    // don't run the init constructor) 
    initializing = true; 
    var prototype = new this(); 
    initializing = false; 

    // Copy the properties over onto the new prototype 
    for (var name in prop) { 
     // Check if we're overwriting an existing function 
     prototype[name] = typeof prop[name] == "function" && 
     typeof _super[name] == "function" && fnTest.test(prop[name]) ? 
     (function(name, fn){ 
      return function() { 
      var tmp = this._super; 

      // Add a new ._super() method that is the same method 
      // but on the super-class 
      this._super = _super[name]; 

      // The method only need to be bound temporarily, so we 
      // remove it when we're done executing 
      var ret = fn.apply(this, arguments);  
      this._super = tmp; 

      return ret; 
      }; 
     })(name, prop[name]) : 
     prop[name]; 
    } 

    // The dummy class constructor 
    function Class() { 
     // All construction is actually done in the init method 
     if (!initializing && this.init) 
     this.init.apply(this, arguments); 
    } 

    // Populate our constructed prototype object 
    Class.prototype = prototype; 

    // Enforce the constructor to be what we expect 
    Class.constructor = Class; 

    // And make this class extendable 
    Class.extend = arguments.callee; 

    return Class; 
    }; 
})(); 

Una vez que ha ejecutado ejecutado este código, entonces eso hace que el siguiente código de insin's answer posible:

var MyWidget = Class.extend({ 
    init: function(widget_name){ 
    this.widget_name = widget_name; 
    }, 

    doSomething: function() { 
    alert('my name is ' + this.widget_name); 
    } 
}); 

ésta es una solución agradable, limpio. Pero estoy interesado en ver si alguien tiene una solución que no requiera agregar nada a jquery.

24

Por qué no utilizar la programación orientada a objetos simple que sí JavaScript proporciona ... mucho antes de jQuery?

var myClass = function(){}; 
myClass.prototype = { 
    some_property: null, 
    some_other_property: 0, 

    doSomething: function(msg) { 
     this.some_property = msg; 
     alert(this.some_property); 
    } 
}; 

A continuación, sólo crea una instancia de la clase:

var myClassObject = new myClass(); 
myClassObject.doSomething("Hello Worlds"); 

simple!

+0

¡Biblioteca independiente, muy agradable! Aunque prefiero la declaración más "clase" como: 'function MyClassName() {};' – plesatejvlk

+9

@CrazyMerlin no debería definir propiedades como alguna_propiedad y alguna_propiedad en el constructor y definir métodos en el prototipo ... de ese modo cada instancia lo obtiene propiedad propia en lugar de compartirlo entre ellos .. –

0

me encontré con este sitio web una impresionante para Uy en javascript Here

Cuestiones relacionadas