覆盖 javascript 函数的 return 语句

发布于 2024-12-19 07:06:24 字数 173 浏览 1 评论 0原文

假设我有一个js函数。从程序中的其他点,我想运行它的代码,但不是它的返回语句。取而代之的是,我想运行一些其他返回语句来引用原始函数范围内的变量。

除了加载函数源、替换返回值并对结果使用 eval 之外,还有其他方法可以做到这一点吗?可以对原始版本进行最小程度的修改,但不应通过添加额外的函数调用来影响原始版本的性能。

Assume I have a js function. From some other point in the program, I want to run its code, but not its return statement. In its place, I would like to run some other return statement that references the variables in the scope of the original function.

Is there a way to do this, other than loading up the function source, replacing the return, and using eval on the result? Minimal modification of the original is possible, though it should not affect the original's performance by adding e.g. an extra function call.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

把时间冻结 2024-12-26 07:06:24

你可以尝试这样的事情,但我不确定它是否符合你的条件。

编辑:修复在 jsfiddle 中工作

// Modified to set all "shared" variables as "members" of the function.
var test = function() {
    test.val = "one";
    test.val2 = "two";
    return 1;   
}

// Using different result
function test2() {
    test();
    return test.val2;
}

You could try something like this, but I'm not sure it meets your conditions.

Edit: Fixed to work in jsfiddle

// Modified to set all "shared" variables as "members" of the function.
var test = function() {
    test.val = "one";
    test.val2 = "two";
    return 1;   
}

// Using different result
function test2() {
    test();
    return test.val2;
}
刘备忘录 2024-12-26 07:06:24

除非您能够重组您的方法以适应 回调 或引入一些其他基于参数的逻辑-flow(不是第三方代码的选项),你运气不好。

这是一个回调示例(fiddle,归功于 dzejkej 的回答

function foo(callback) {
    var x = 2;   
    // pass your values into the callback
    return callback ? callback.call(this, x) : x * 2;
}
document.write(foo());
document.write("<hr/>");
// specify the parameters for your callback
document.write(foo(function(x){ return x * 4;}) );

Unless you're able to restructure your methods to accommodate a callback or introduce some other parameter-based logic-flow (not an option for 3rd party code), you're out of luck.

Here's a callback sample (fiddle, credit to dzejkej's answer)

function foo(callback) {
    var x = 2;   
    // pass your values into the callback
    return callback ? callback.call(this, x) : x * 2;
}
document.write(foo());
document.write("<hr/>");
// specify the parameters for your callback
document.write(foo(function(x){ return x * 4;}) );
猫瑾少女 2024-12-26 07:06:24

您可以引入一个回调函数,如果可用,将调用该函数,否则将返回“标准”值。

function test(callback) {
  // ...
  return callback ? callback.call(this) : /* original value returned */ "xyz";
}

test(function() { /* "this" is same as in test() */ });

编辑:

如果您想在回调内传递变量,那么您只需将它们列在 .call() 函数中即可。

示例:

function test(callback) {
  var a = 4;
  var b = 2;
  // ...
  return callback ? callback.call(this, a, b) : a * b;
}

test(); // 8
test(function(a, b) { return a + b; }); // 6

参见这个小提琴

You can introduce a callback function that will get called if available otherwise "standard" value will be returned.

function test(callback) {
  // ...
  return callback ? callback.call(this) : /* original value returned */ "xyz";
}

test(function() { /* "this" is same as in test() */ });

EDIT:

If you want to pass variables inside callback then you just list them in the .call() function.

Example:

function test(callback) {
  var a = 4;
  var b = 2;
  // ...
  return callback ? callback.call(this, a, b) : a * b;
}

test(); // 8
test(function(a, b) { return a + b; }); // 6

See this fiddle.

冰之心 2024-12-26 07:06:24

假设您将外部作用域函数的变量保留在单个对象中,您可以尝试如下操作:

function original(a, b, c, rep) {
    var data = {};

    // Do some fancy stuff but make sure to keep everything under data
    data.a = a.replace(/foo/, 'bar');
    ...

    if ( Object.prototype.toString.call(rep) === '[object Function]' )
        return rep.call(data);

    return data;
}

function replacement() {
    return 'foo' + this.a;
}

// Now let's make use of both the original and the replacement ...
console.log(original('foo', x, y)); // => {a: "bar", b: ...}

console.log(original('foo', x, y, replacement)); // => {a: "foobar", b: ...}

希望,这就是您所要求的。
干杯

Provided that you would keep variables of the outer scope function within a single object, you could try something like the following:

function original(a, b, c, rep) {
    var data = {};

    // Do some fancy stuff but make sure to keep everything under data
    data.a = a.replace(/foo/, 'bar');
    ...

    if ( Object.prototype.toString.call(rep) === '[object Function]' )
        return rep.call(data);

    return data;
}

function replacement() {
    return 'foo' + this.a;
}

// Now let's make use of both the original and the replacement ...
console.log(original('foo', x, y)); // => {a: "bar", b: ...}

console.log(original('foo', x, y, replacement)); // => {a: "foobar", b: ...}

Hope, it's what you where asking for.
cheers

梦里兽 2024-12-26 07:06:24

我认为您确实误解了返回语句的概念。函数的 return 语句将仅返回一个值或一个对象,如果没有指定返回参数,则返回 undefined。

如果您想做的只是执行一个函数,但“不是它的返回语句”,那么您只需调用该函数,而不对返回的值/对象执行任何操作:

但是,如果您的意思是您想要执行一个函数但不执行其返回语句的“参数”,那么字面意思是有选择地执行函数体的任意部分。据我所知,这是不可能的(不使用反射来获取函数定义,修改定义,然后动态调用修改后的版本 - 你说你不想这样做)。

I think you really misunderstand the concept of return statement. The return statement of a function will simply return a value, or an object, or undefined if there is no return parameter specified.

If all you're trying to do is execute a function but "not its return statement" than you would just invoke the function and not do anything with the returned value/object:

However, if what you mean is that you would like to execute a function but not execute the "parameter" to its return statement then that literally means to selectively execute an arbitrary portion of the body of a function. And as far as I know that is not possible (without using reflection to get the function definition, modify the definition, and then dynamically invoking the modified version - which you said you didn't want to do).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文