当函数的属性函数被调用时,是否可以修改函数本身

Is it possible to modify a function itself when its property function is called?

本文关键字:函数 修改 是否 属性 调用      更新时间:2023-09-26

基本上我想这样做:

someFunction() // do something
someFunction.somePropertyFunction()
someFunction()  // Now someFunction is modified; it should now exhibit a different behaviour

这可能吗?

编辑:

我不是在寻找@Kolink的建议。基本上,我想通过调用函数的一个属性函数来增强函数的功能。

具体来说,我需要:1。可以访问我的属性函数中的原始函数(使用this完全可行),以及2。将一个新函数绑定到原始函数的名称(我不确定这是否可能)。

需要明确的是,我无法访问要增强的函数的内部定义。我想把一个函数附加到function.prototype(这样它就可以作为我想增强的函数的属性),然后我会调用func.augmentThis(),然后func应该被增强。但我不确定是怎么做的,因此有一个问题:P

轻松。这里有一个例子:

var derp = 123;
someFunction = function() {alert(derp);};
someFunction.somePropertyFunction = function() {derp = 456;};
someFunction(); // alerts 123
someFunction.somePropertyFunction();
someFunction(); // alerts 456

好吧,这是一个过于简单化的例子,但是的,这是完全可能的。

如果你的问题是作为属性附加到另一个函数的函数是否有方法访问它所附加的函数,答案是否定的。毕竟,同一个函数可以附加到任意数量的对象函数。

因此,一种选择是在附加于它并旨在改变其行为的函数中明确提及"母亲"函数:

function f (n) {  alert (n + f.offset); }
f.offset = 0;
f.change_offset = function (i) { f.offset = i; };
f (1);                  //1
f.change_offset (100);
f (1);                  //101

这里,f被硬连接到change_offset的定义中。如果这让你感到困扰,或者你想要一些更通用的东西,那么写一个小例程来将一个函数设置为另一个函数的属性,同时将其this绑定到附加到的函数:

function set_func_as_func_prop ( propname, func_to_set, func_to_set_on ) {
    func_to_set_on[propname] = func_to_set.bind(func_to_set_on);
}

现在你可以编写更通用的函数

function change_offset (i) {
    this.offset = i;
}

并将其设置在CCD_ 6或任何其他功能上。

set_func_as_func_prop ("change_offset", change_offset, f);
set_func_as_func_prop ("change_offset", change_offset, g);

排序:

function someFunction() {
    return realFunction.apply(this, arguments);
}
function someFunctionA(name) {
    return 'Hello, ' + name + '!';
}
function someFunctionB(name) {
    return 'Goodbye, ' + name + '...';
}
var realFunction = someFunctionA;
someFunction.somePropertyFunction = function () {
    realFunction = someFunctionB;
};

当然有可能。不建议这样做,但这是可能的。例如:

function a() {
    alert("a");
}
function b() {
    alert("b");
}
function c() {
    return c.f.apply(this, arguments);
}
c.f = a;
c.toggle = function () {
    c.f = c.f === a ? b : a;
};

现在让我们测试一下:

c();        // alerts "a"
c.toggle();
c();        // alerts "b"

查看演示:http://jsfiddle.net/LwKM3/

我想给Function.prototype附加一个函数。然后我需要将一个新函数绑定到原始函数的名称(我不确定这是否可能)。

这确实是不可能的,你不知道函数指的是什么。并且不能更改函数的内部表示,它是不可变的。

你唯一能做的就是创建一个新函数并返回,让方法的调用者以某种方式使用它——特别是将它分配给原始变量:

somefunction = somefunction.augmentSomehow();

你的方法看起来是这样的:

Function.prototype.augmentSomehow = function() {
    var origFn = this;
    return function() {
        // in here, do something special
        // which might include invoking origFn() in a different way
    };
};

不确定这是否有帮助,但我会以以下方式实现所描述的问题:

// defined by somebody else - unknown to developer
var someFunction = function() {
    alert("this is initial behavior");
}
someFunction(); // returns "this is initial behavior"
// defines parent object on which someFunction() is called
var parentObject = this; // returns window object (as called direclty in the
// browser)
// if you are calling someFunction from some object (object.someFunction())
// it would be:
// var parentObject = object;
// augumentThis definition
someFunction.augumentThis = function() {
    var newFunction = function() {
        alert("this is changed behavior");
    };
    parentObject.someFunction.somePropertyFunction = function() {
        parentObject.someFunction = newFunction;
        parentObject.someFunction();
    };
};
someFunction.augumentThis();            // change function behavior
someFunction();                         // "this is initial behavior"
someFunction.somePropertyFunction();    // "this is changed behavior"
someFunction();                         // "this is changed behavior"