2016-01-16 5 views
1

Чтобы понять это функция на странице HTML и генерируется, я не могу изменить сгенерированный код:Как динамически изменять содержимое функции с помощью JavaScript

function Update_qu7260() { 
    var newVal = '' 
    for(var idx = 0; idx < 2; idx++) 
    { 
    var test 
    if(idx == 0) test = text7263 
    else if(idx == 1) test = text7265 
    if(test.matchObj) newVal += test.leftSel + "-" + test.matchObj.rightSel + "," 
    } 
    newVal = newVal.substring(0, newVal.length-1) 
    VarQuestion_0001.set(newVal) 
    qu7260.hasBeenProcessed=false; 
    doImmFeedback('qu7260'); 
} 
var qu7260 = new Object(); 
... 
qu7260.updFunc = Update_qu7260; 
var qObj=[qu7260]; 

Примечание в указанном выше количестве «7260», цифры начинаются с 1, поэтому их много, и каждый Update_###() будет отличаться, поэтому я не могу переписать их с помощью «жесткого» кода. Мой код находится во внешнем файле JavaScript и выполнен OnLoad:

... 
var updFunc = qObj[0].updFunc.toString(); 
if(updFunc.indexOf('doImmFeedback(')!=-1){ 
    updFunc = updFunc.replace('doImmFeedback','doImmQuestionFeedback'); // do my function 
    updFunc = updFunc.replace('function ',''); // remove the word function 
    var funcName = updFunc.substr(0,updFunc.indexOf('(')); // get the function name e.g. Update_qu7260 
    updFunc = "window['" + funcName + "']=function" + updFunc.replace(funcName,''); 
    eval(updFunc); 
} 
... 

Когда я изменяю Eval() для предупреждения() я могу видеть, что это правильно, однако, Eval() не ставит каких-либо ошибок и моя функция doImmQuestionFeedback не вызывается. Когда я потом делаю alert(qObj[0].updFunc.toString()), я вижу оригинальную функцию.

Казалось бы, что я предоставил информацию, которая является слишком сложным, поэтому следующий код лучший пример:

function hi(){alert('hi');} 
function changeHi(){ 
    hi(); // I get an alert box with hi 
    newHi = "function hi(){alert('hi there');}" 
    eval(newHi); 
    hi(); // I get an alert box with hi 
    window.setTimeout('hi()',500); // I get an alert box with hi 
} 
window.setTimeout('changeHi()',500); 

Ниже приводится оригинальный вопрос:

У меня есть предопределенная функция, которую я не создал, однако, я знаю, что это имя, поэтому я могу получить эту функцию, а затем меняю ее:

var funcText = window.updateFunc.toString(); 
funcText = funcText.replace('doSomeOtherFunction(','doMyFunction('); 

Как обновить фактическую функцию, чтобы она делала все, что она делала раньше, за исключением того, что она теперь вызывает doMyFuntion()?

Ниже приведен пример, который поможет визуализировать то, что я хочу сделать, фактическая функция, которую мне нужно изменить, очень сложна. У меня есть:

function updateFunc(whatToUpdate,true){ 
    ... - do lots of stuff. 
    var retVal = doSomeOtherFunction(whatToUdate); 
    ... - do lots of stuff based on retVal 
} 

Мне нужно изменить это:

function updateFunc(whatToUpdate,true){ 
    ... - do lots of stuff 
    var retVal = doMyFunction(whatToUdate); 
    ... - do lots of stuff based on retVal, I have had a chance to change retVal 
} 

Тогда первое, что моя функция будет делать это вызов doSomeOtherFunction() проверить/изменить возвращаемое значение, а затем возвращает значение в updateFunc().

Я пытался манипулировать funcText выше:

funcText = 'window.updateFunc = function(...'; 
eval(funcText); 

без успеха.

+0

Я нашел проблему, все мои вина, извините за это. Обратите внимание на строку 'qu7260.updFunc = Update_qu7260;', как только я сменил функцию, мне нужно снова вернуть ее обратно в объект, я думал, что это всего лишь указатель, но это была сама функция, и это запускается в другом месте через 'this .updFunc() '. – Peter

ответ

0

Я думаю, что вы слишком сложны. Если у вас есть только doMyFunction и doSomeOtherFunction, чтобы переключаться между ними, вы можете просто создать флаг где-нибудь, говорящий вам использовать тот или иной при использовании в if -statement.

Если вы хотите вызвать функцию с именем, которое вы не знаете заранее, и вы получите только имя во время выполнения, вы можете либо принять функцию для вызова в качестве параметра, либо принять имя функции в качестве параметра и назовите его так: var retVal = window[functionName](); (предполагается, что functionName является собственностью объекта window).

Я бы настоятельно рекомендовал напрямую принимать функцию в качестве параметра, поскольку функция не может быть определена в глобальной области.

EDIT: После вашего разъяснения, я думаю, я могу дать вам удовлетворительный ответ:

, если у вас есть строка, как var functionString = "function updateFunc(whatToUpdate){var retVal = doMyFunction(whatToUpdate);}";

Вы можете определить функцию с помощью Function объекта: window.updateFunc = new Function("whatToUpdate", "return (" + functionString + ")(whatToUpdate)"); Это заменит уже существующую функцию, и вы можете дать ей любую действительную строку функции, которую вы хотите, до тех пор, как вы знаете, и укажите аргументы.

+0

Спасибо за ввод, однако, то, что я спросил, это то, на что мне нужен ответ. В основном у меня есть строковая переменная, содержащая функцию, и я хочу, чтобы она стала функцией, мне также нужно заменить существующую функцию. Это очень сложно, и код - пример - спасибо. – Peter

+0

Проверьте, что выше, я думаю, я получил то, что вы хотели сейчас. – patrick96

+0

См. Обновленный вопрос - спасибо. – Peter

1

Это может быть достаточно близко к тому, что вы ищете.

Если у вас есть эта оригинальная функция:

function originalFunc(val) { 
    // this function converts input string to upper case 
    return val.toUpperCase(); 
} 

Теперь вы хотите, чтобы заменить его на что-то до или после выполнения этой функции (в данном примере, мы выполняем и раньше, конечно, до или после того, как Безразлично» в данном случае имеет значение).

// we preserve orignal function 
var originalFunc_save = originalFunc; 

// now we override the original function with this block  
var originalFunc = function(text) { 
    // lets call the orignal function 
    text = originalFunc_save(text); 

    // now do our custom thing 
    return text.split('').reverse().join(''); 
} 

Так что наш тест должен работать.

var text = 'This is a test'; 
console.log(originalFunc(text)); 

Выход:

TSET A SI SIHT 

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

UPDATE: Я обновляю этот код, чтобы использовать строковую переменную, указывающую на исходную функцию. Я думаю, это то, чего хотел OP.

Оригинальный код, который определяется некоторой библиотеки

function originalFunc(val) { 
    // this function converts input string to upper case 
    return val.toUpperCase(); 
} 

Теперь мы используем переменную FUNC строку, чтобы указать на эту функцию и выполнить ее.

var text = 'This is a test'; 
var func = 'originalFunc'; 
text = window[func](text); 
console.log(text); 

Выход: Конечно, мы получаем исходный предполагаемый результат, потому что мы его не переопределили.

THIS IS A TEST 

Теперь мы пишем наш код, чтобы переопределить исходное поведение функции, используя строку, указывающую на функцию.

// let's define a new function string 
var funcSaved = func + '___saved'; 

// now preserve the original function code 
window[funcSaved] = window[func]; 

// override the original function code block 
window[func] = function(text) { 
    // lets call the orignal function 
    text = window[funcSaved](text); 

    // now do our custom thing 
    return text.split('').reverse().join(''); 
} 

// let's test the code 
text = 'This is a test'; 
text = window[func](text); 
console.log(text); 

Выход:

TSET A SI SIHT 
+0

Спасибо за это, однако, весь ваш код жестко связан, у меня есть строковая переменная, и мне нужно это, чтобы стать функцией. На самом деле я не знаю названия функции, поскольку она является частью другого объекта. например 'funcText = obj1234.updateFunc.toString();' – Peter

+0

О, я думал, что вы знаете, что такое имя оригинальной функции, но даже если вам нужно переопределить функцию, на которую ссылается строковая переменная, все же выполнимо. Позвольте мне перечитать ваш пост и придумать код с помощью переменной. – Will

+0

@Peter - Ваше второе утверждение говорит, что вы знаете имя функции, но это не имеет значения. :) – Will

0

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

//Someone else's function 
function externalFunction(foo){ 
    return "some text"; 
} 

//Your function 
function myFunction(value){ 
    //Do something 
} 

//Override 
var externalFunction = (function(){ 
    var original = externalFunction; //Save original function 

    return function(){ 
     var externalFunctionReturnValue = original.apply(this, arguments); 

     return myFunction(externalFunctionReturnValue); 
    } 
})(); 

Я сильно sugest не использовать Eval, но так как вы хотите, чтобы разобрать JavaScript из строки:

function hi(){alert('hi');} 
function changedHi(){ 
    hi(); // I get an alert box with hi 
    newHi = "window['hi'] = function(){alert('hi there');}" 
    eval(newHi); 
    hi(); // I get an alert box with hi there 
    window.setTimeout('hi()',500); // I get an alert box with hi there 
} 
window.setTimeout('changedHi()',500); 

UPDATE:

Этот код snippet, который является вашим исходным кодом:

<script type="text/javascript"> 
    function doImmFeedback(foo){ 
     console.log("DoImmFeedback: " + foo); 
     } 

     function Update_qu7260() { 
     console.log("Some code") 
     doImmFeedback('qu7260'); 
     } 
    </script> 

    <script type="text/javascript"> 
     var qu7260 = new Object(); 
     qu7260.updFunc = Update_qu7260; 
     var qObj=[qu7260]; 

     var updFunc = qObj[0].updFunc.toString(); 
     if(updFunc.indexOf('doImmFeedback(')!=-1){ 
     updFunc = updFunc.replace('doImmFeedback','doImmQuestionFeedback'); // do my function 
     updFunc = updFunc.replace('function ',''); // remove the word function 
     var funcName = updFunc.substr(0,updFunc.indexOf('(')); // get the function name e.g. Update_qu7260 
     updFunc = "window['" + funcName + "']=function" + updFunc.replace(funcName,''); 
     console.log(updFunc); 
     eval(updFunc); 
     } 

     function doImmQuestionFeedback(foo){ 
     //Your function 
     console.log("doImmQuestionFeedback: " + foo); 
     } 

     Update_qu7260(); //This executes your doImmQuestionFeedback 
    </script> 

Итак, если ваша функция не запущена, ваша функция не входит в глобальную область или что-то еще происходит, и мы не можем знать, не больше ли информации. Проверьте консоль разработчика на наличие ошибок javascript.

+0

Может быть, мое название вопроса не так? Мне нужно построить функцию в переменной, а затем преобразовать эту переменную в фактическую функцию - спасибо. – Peter

+0

Я настоятельно рекомендую не использовать eval, но если ваша переменная содержит действительный javascript, ваш код должен работать; eval ('function test() {console.log ("foo");}'); контрольная работа(); Итак, напишите полный код или сообщите нам больше информации;) –

+0

Пожалуйста, ознакомьтесь с обновленным вопросом - спасибо. – Peter

0

Я считаю, что это действительный прецедент для забытой функции JavaScript with.

Основная идея: вы называете оригинальный updateFunc поставлять свою собственную версию doSomeOtherFunction к нему с помощью with инъекции имен:

function updateFunc(whatToUpdate,true){ 
    ... - do lots of stuff. 
    var retVal = doSomeOtherFunction(whatToUdate); 
    ... - do lots of stuff based on retVal 
} 


function patchUpdateFunc() { 

    var original_doSomeOtherFunction = window.doSomeOtherFunction; 
    var original_updateFunc = window.updateFunc; 

    function doMyFunction() { 
    // call original_doSomeOtherFunction() here, 
    // do your own stuff here. 
    }; 

    window.updateFunc = function() { 
    with ({doSomeOtherFunction: doMyFunction}) { 
     return original_updateFunc.apply(this, arguments); 
    } 
    } 
} 

patchUpdateFunc(); 
+0

См. Обновленный вопрос - спасибо. – Peter

+0

@ Питер Если вы считаете, что упростили это, тогда нет. У вас есть два несвязанных фрагмента кода (старый и новый). –

+0

Хорошо, вы можете помочь с новым? – Peter

0

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

function updateFunc(whatToUpdate, param){ // the initial function 
     ... 
     var retVal = doSomeOtherFunction(whatToUpdate); 
     return retVal; 
    } 

    // formation of unnamed function as string 
    var newfunc = updateFunc.toString().replace('function updateFunc', 'function ').replace('doSomeOtherFunction(', 'doMyFunction('); 

    function doMyFunction(whatToUpdate){ // your new function, just for example 
     console.log(parseInt(whatToUpdate) * 10); 
    } 

    var newUpdateFunc; 
    // declaring new version of 'updateFunc' function 
    // which is stored in 'newUpdateFunc' variable 
    eval("newUpdateFunc = " + newfunc); 

    newUpdateFunc(3); // outputs '30' 
+0

Пожалуйста, ознакомьтесь с обновленным вопросом - спасибо. – Peter

Смежные вопросы