更改没有代理的功能行为

时间:2016-02-22 10:17:48

标签: javascript monkeypatching

我可以这样做:

foo

有没有办法改变第一个DateTime而不是创建新功能? 我需要它来修补一些依赖,而不重新创建对象的整个层次结构。

我需要在库中修补构造函数,只需在每次调用时添加警报。但是没有玩弄原型

1 个答案:

答案 0 :(得分:3)

不,你不能修改函数foo所指的。您只能让foo引用一个能够满足您需求的新功能。一种方法是使用toString方法,但最好尽可能避免使用,因为你得到的函数与原始函数不同;它可以访问的范围将是不同的。

通常,您需要代理/包装器,例如:

// The original foo
var foo = function(arg) {
    return "original foo says '" + arg + "'";
};
snippet.log(foo("bar"));

// Let's wrap it
(function() {
    var originalFoo = foo;
    foo = function() {
        return originalFoo.apply(this, arguments) + " plus updated foo";
    };
})();
snippet.log(foo("bar"));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

这不会创建对象或类似的层次结构,它只包装foo

如果foo构造函数(我们称之为Foo),您还需要复制Foo.prototype

// The original Foo
var Foo = function(arg) {
  this.value = "original foo";
  this.arg = arg;
};
Foo.prototype.getArg = function() {
  return this.arg;
};
var f1 = new Foo("bar");
snippet.log(f1.getArg());

// Let's wrap it
(function() {
    var originalFoo = Foo;
    Foo = function() {
      var rv = originalFoo.apply(this, arguments);
      this.arg += " (plus more from augmented foo)";
      return rv;
    };
    Foo.prototype = originalFoo.prototype;
})();
var f2 = new Foo("bar");
snippet.log(f2.getArg());
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

当然,如果你需要在Foo.prototype上包装一个函数,你可以像我在第一个例子中的foo那样做:

// The original Foo
var Foo = function(arg) {
  this.value = "original foo";
  this.arg = arg;
};
Foo.prototype.getArg = function() {
  return this.arg;
};
var f = new Foo("bar");
snippet.log(f.getArg());

// Let's wrap its getArg
(function() {
    var originalGetArg = Foo.prototype.getArg;
    Foo.prototype.getArg = function() {
      return originalGetArg.apply(this, arguments) + " updated";
    };
})();
snippet.log(f.getArg());
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

请注意,在创建f对象之后我们将原型函数包装起来并不重要。