覆盖函数而不删除静态属性

时间:2012-10-02 07:51:58

标签: javascript function static constructor extend

如果我有这样的功能:

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

然后分配一个这样的静态属性:

a.static = 'foo';

但是我想用另一个函数覆盖这个函数:

var old = a;

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

a.static // undefined

由于我为a分配了一个新函数,因此它的静态属性会丢失。是否有一种简洁的方法来保持静态属性而不循环并手动复制它们?

更新

这是一个真实世界的场景:在Bootstrap jQuery插件中,作者将默认值分配给属性函数,如下所示:

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

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

因此,如果我想“扩展”我通常会做的原型:

var old = $.fn.modal;

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

但这会使

$.fn.modal.defaults === undefined

这将破坏功能,因为默认值会丢失。我想知道在javascript中是否有一种偷偷摸摸的方式来改变只有函数而不会丢失静态属性。

1 个答案:

答案 0 :(得分:3)

不,你不能这样做。替换对象(函数)总是带有任何属性。

这里有两个解决方案,都涉及将属性从旧对象转移到新对象。

第一种(推荐)方法是复制属性,可以使用$.extend方便地完成:

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

第二个选项是将新函数的原型动态设置为旧函数。例如,在某些浏览器中,这将起作用:

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

然而,这是非标准的,可能会引起并发症;不要这样做。