2010-07-22 6 views
5

He estado experimentando con un patrón de diseño en Javascript que me permitiría tener lo que parecen ser funciones singleton que pueden ser anuladas por funciones de instancia.A (algo oscura) Pregunta de herencia de Javascript

He aquí un breve ejemplo:

Date.tomorrow = function() { 
    return Date.today().add(1).days(); 
} 

(function(p) { 

    p.tomorrow = function() { 
    var date = this.clone().clearTime(); 
    return date.equals(Date.tomorrow()); 
    } 

})(Date.prototype); 

Así que hay dos funciones tomorrow(). Cuando se llama desde la función Fecha directamente:

>>> Date.tomorrow() 
=> Fri Jul 23 2010 00:00:00 GMT-0500 (CST) { _orient=1, more...} 

Pero cuando se instancia una instancia de fecha primero:

>>> var date = new Date() 
>>> date.tomorrow() 
=> false 

estoy dejando una gran cantidad cabo como estoy seguro que usted puede decir, pero es de esperar que entender el punto. Mi pregunta es esta: ¿cuál es la relación de la primera función tomorrow() con el objeto Date? ¿A qué está unido, exactamente?

Digamos que estaba haciendo esto con una función normal que no estaba destinada a ser un constructor. ¿Es posible llamar a la función aumentada desde la función original?

En una función constructora que podría hacer esto:

this.constructor.functionName(); 

pero si la función no está siendo utilizado como un constructor, obviamente, no existiría la referencia constructor. ¿Hay alguna otra manera de acceder a esa función aumentada?

El impulso detrás de esta pregunta proviene de mi trabajo reorganizando el código JS para un proyecto. Estamos implementando el sistema Sprockets para dividir nuestro código fuente en módulos, en los que se está decorando básicamente un espacio de nombres base a medida que avanzamos en lugar de agruparlo todo en una definición de objeto en línea ilegible.

Tenemos un cable de evento bastante grande y épico, que es bueno dividir en funciones separadas, pero prefiero no tener que llamar a cada función individualmente; en su lugar, me gustaría una superfunción que llame a todas las subfunciones de una vez.

Siempre pude crear una función all() o algo así para lograr esto, pero se vería mucho más limpio desde un punto de vista API si llamar a una función de nivel superior ejecutara todas las subfunciones que se le habían asignado.


Gracias a la respuesta de Francisco ahora tengo una implementación en funcionamiento de lo que estaba pensando. Aquí hay un ejemplo en caso de que alguien tenga curiosidad.

var Namespace = {}; 

var Namespace.wireup = (function() { 

    return function() { 
    var self = arguments.callee; 
    self.eventWireup1(); 
    self.eventWireup2(); 
    }; 

})(); 

(function (W) { 

    function eventWireup1() { console.log('first function'); }; 
    function eventWireup2() { console.log('second function'); }; 

    $.extend(W, { 
    eventWireup1: eventWireup1, 
    eventWireup2: eventWireup2 
    }); 

})(Namespace.wireup); 

El beneficio de esta API es que se puede hacer esto:

>>> Namespace.wireup.eventWireup1(); 
=> first function 
>>> Namespace.wireup.eventWireup2(); 
=> second function 
>>> Namespace.wireup(); 
=> first function 
=> second function 
+1

Acaba de salir de la curiosidad; ¿has mirado el Yahoo! Biblioteca de eventos? Sé que no es específicamente por lo que pregunta ... pero parece que lo que está pidiendo puede que no necesite si tuviera una alternativa decente. (http://developer.yahoo.com/yui/event/) – Steve

+0

@Steve mi pregunta no está realmente relacionada con el enlace de eventos per se, sino más bien con una forma de modularización. Hay ciertos tipos de cableado de eventos que deseo poder invocar tanto implícita como explícitamente. Además, ya estoy usando jQuery para eventos que me gustan mejor que YUI personalmente. –

Respuesta

0

Desde arguments.callee está en desuso que pensé que debería actualizar esta pregunta con un ejemplo de lo que terminé haciendo la transición a eso es más correcto y también compatible con el modo estricto.

var Namespace = {}; 

(function() { 
    Namespace.wireup = function self() { 
    self.eventWireup1(); 
    self.eventWireup2(); 
    } 
})(); 

(function (self) { 
    self.eventWireup1 = function() { console.log('first function') } 
    self.eventWireup2 = function() { console.log('second function') } 
})(Namespace.wireup); 
2

Fecha es una función() del objeto de la ventana, y va a conectar otra función a la función. ¿Extraño eh?

Prueba esto:

function a() 
{ 
    return 10; 
} 

a.e = "oO"; 

typeof(a); 
typeof(a.e); 

para acceder al correo desde el interior de una se puede utilizar la propiedad destinatario de la llamada de argumentos, como:

function a() { 
    return arguments.callee.e; 
} 

a.e = "Oo" 

a(); 
+0

Sí, es extraño; pero, en general, la herencia de Javascript es extraña;) Mi pregunta es: ¿puede acceder a.e desde dentro de la función a()? ¿Cómo lo haría sin usar el nombre completo? –

+0

'arguments.callee' es lo que estaba buscando! Gracias. –