2012-10-02 48 views
6

Si tengo una función como esta:Anulación de una función sin quitar propiedades estáticas

function a() { 
    console.log('a'); 
} 

y luego asignar una propiedad estático como sigue:

a.static = 'foo'; 

Pero digo que quiero para anular la función con otra función como esta:

var old = a; 

a = function() { 
    console.log('new'); 
    old.call(this); 
}; 

a.static // undefined 

Desde que asigna una nueva función a a, sus propiedades estáticas están perdidas. ¿Existe una manera ordenada de mantener las propiedades estáticas sin bucles y copiarlas manualmente?

Actualización:

He aquí un verdadero escenario mundial: En plugins Bootstrap jQuery, el autor asigna por defecto a la función propiedad como esta:

$.fn.modal = function() { 
    // some code 
}; 

$.fn.modal.defaults = { // some object }; 

Así que si quiero para "extender" la prototipo que haría normalmente:

var old = $.fn.modal; 

$.fn.modal = function() { 
    // do my thing 
    old.apply(this, arguments); 
} 

Pero que haría

$.fn.modal.defaults === undefined 

Esto cortará la funcionalidad, porque los valores predeterminados se pierden. Me preguntaba si hay una manera furtiva en javascript para cambiar solo la función sin perder las propiedades estáticas.

+1

¿Puedo preguntar cuál es el uso de tal enfoque? Se ve realmente desordenado. – Christoph

+0

Lo estoy preguntando porque en los plugins jQuery bootstrap, el autor asigna valores predeterminados estáticos como un objeto adjunto al prototipo. Entonces, si quiero extenderlo, pierdo los valores predeterminados (y posiblemente otras propiedades) que se adjuntan. Además, porque tengo curiosidad de saber si hay una forma de cambiar la función solamente, no sus propiedades estáticas. – David

Respuesta

3

No, no puedes hacer esto. Reemplazar el objeto (función) siempre toma cualquier propiedad con él.

Aquí hay dos soluciones, y ambas implican la transferencia de las propiedades del objeto antiguo al nuevo.

El primer enfoque (recomendado) es copiar las propiedades, que puede hacerse convenientemente con $.extend:

$.fn.plugin = $.extend(function() { ... }, $.fn.plugin); 

La segunda opción sería la de establecer dinámicamente el prototipo de la nueva función de ser la función de edad . Por ejemplo, en algunos navegadores esto funcionaría:

var f = function() { ... }; 
f.__proto__ = $.fn.plugin; 
$.fn.plugin = f; 

Sin embargo, esto no es estándar y podría dar lugar a complicaciones; no lo hagas

+0

No pensé en '$ .extend' como una forma de copiar propiedades de funciones, pero funciona muy bien. Gracias – David

Cuestiones relacionadas