【问题标题】:Overriding a function without removing static properties在不删除静态属性的情况下覆盖函数
【发布时间】:2012-09-23 01:49:52
【问题描述】:

如果我有这样的功能:

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 中是否有一种偷偷摸摸的方式来更改 仅函数 而不会丢失静态属性。

【问题讨论】:

  • 请问这种方法有什么用?看起来真的很乱。
  • 我问是因为在引导 jQuery 插件中,作者将静态默认值分配为附加到原型的对象。因此,如果我想扩展它,我会丢失附加的默认值(可能还有其他属性)。另外,因为我很好奇是否有办法只改变函数,而不是改变静态属性。

标签: javascript function static constructor extend


【解决方案1】:

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

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

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

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

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

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

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

【讨论】:

  • 我不认为$.extend 是一种复制函数属性的方法,但它工作得很好。谢谢
猜你喜欢
  • 2019-02-06
  • 2018-02-27
  • 1970-01-01
  • 2016-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多