Zmiana funkcji poprzez współpracę z ciągów kod źródłowy może być całkiem proste. Aby zrobić to w konkretnym przypadku, spróbuj:
eval(doSomething.toString().replace(/}\s*$/, ' return id; $&');
Teraz doSomething
zwraca identyfikator. Zwykle nie jestem fanem eval
, ale normalne techniki aspect oriented programming nie mają tu zastosowania ze względu na wymaganie dostępu do zmiennej lokalnej.
Jeśli doSomething
już zwraca wartość, spróbuj:
eval(doSomething.toString().replace(/}\s*$/, ' window.someID = id; $&');
Aby przekształcić funkcję, musimy uczynić kod oceny w zakresie globalnym:
function insertCode(func, replacer, pattern) {
var newFunc = func.toString().replace(pattern, replacer);
with (window) {
eval(newFunc);
}
}
function after(func, code) {
return insertCode(func, function (old) { code + old }, /}\s*$/);
}
...
after(doSomething, 'return id;');
Jeśli chcesz przerobić metody i anonimowe funkcje powiązane ze zmiennymi, zmień insertCodeBefore
na:
function insertCode(funcName, replacer, pattern) {
var newFunc = eval('window.' + funcName).toString().replace(pattern, replacer);
eval('window.' + funcName + '=' + newFunc);
}
...
function Foo() {}
Foo.prototype.bar = function() { var secret=0x09F91102; }
...
after('doSomething', 'return id;');
after('Foo.prototype.bar', 'return secret;');
Zwróć uwagę, że pierwszym argumentem funkcji są teraz ciągi. Możemy zdefiniować inne funkcje:
function before(func, code) {
return insertCode(func, function (old) {old + code}, /^function\s+\w+\([^)]*\)\s+{/);
}
function around(func, beforeCode, afterCode) {
before(func, beforeCode);
after(func, afterCode);
}
Jaka jest funkcja "zablokowana"? – Lazarus
Możliwy duplikat [Czy istnieje sposób na zawijanie wszystkich metod JavaScript za pomocą funkcji?] (Http://stackoverflow.com/questions/3919134/is-there-a-way-to-wrap-all-javascript-methods- with-a-function) –