переопределение оператора возврата функции JavaScript - PullRequest
2 голосов
/ 03 декабря 2011

Предположим, у меня есть функция js. С какой-то другой точки в программе я хочу запустить ее код, но не оператор return. Вместо этого я хотел бы запустить другой оператор return, который ссылается на переменные в области действия исходной функции.

Есть ли способ сделать это, кроме загрузки источника функции, замены возврата и использования eval для результата? Возможна минимальная модификация оригинала, хотя она не должна влиять на производительность оригинала, добавляя, например, дополнительный вызов функции.

Ответы [ 5 ]

3 голосов
/ 03 декабря 2011

Вы можете попробовать что-то подобное, но я не уверен, что оно соответствует вашим условиям.

Редактировать : исправлено для работы в 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;
}
1 голос
/ 03 декабря 2011

Если вы не можете реструктурировать свои методы, чтобы приспособить обратный вызов или ввести какой-то другой логический поток на основе параметров (не вариант для стороннего кода), вам не повезло.

Вот пример обратного вызова ( скрипка , кредит ответ 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;}) );
1 голос
/ 03 декабря 2011

Вы можете ввести функцию обратного вызова, которая будет вызываться, если она доступна, в противном случае будет возвращено «стандартное» значение.

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

См. эту скрипку .

0 голосов
/ 03 декабря 2011

При условии, что вы будете хранить переменные функции внешней области внутри одного объекта, вы можете попробовать что-то вроде следующего:

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: ...}

Надеюсь, это то, что вы просите.
веселит

0 голосов
/ 03 декабря 2011

Я думаю, вы действительно неправильно поняли концепцию оператора возврата . Оператор return функции просто вернет значение, или объект, или неопределенный, если не указан возвращаемый параметр .

Если все, что вы пытаетесь сделать, это выполнить функцию, но не "оператор возврата", тогда вы просто вызовете функцию и ничего не сделаете с возвращенным значением / объектом:

Однако, если вы имеете в виду, что вы хотели бы выполнить функцию, но не выполнить «параметр» для ее оператора return, то это буквально означает выборочное выполнение произвольной части тела функции. И насколько я знаю, это невозможно (без использования отражения, чтобы получить определение функции, измените определение, а затем динамически вызывайте модифицированную версию - что вы сказали, что не хотите делать).

...