如何使用JavaScript

时间:2016-01-16 19:39:14

标签: javascript

为了帮助理解这个功能在html页面中生成,我无法更改生成的代码:

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];

请注意上面的数字&#34; 7260&#34;,数字从1开始,因此有很多,每个Update_###()都不同,所以我不能用&#34重写它们;硬连线&#34;码。我的代码位于外部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()更改为alert()时,我可以看到它是正确的,但是,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);

没有成功。

5 个答案:

答案 0 :(得分: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

如果必须覆盖类中的函数,则此方法也有效。我们唯一需要注意的是选择一个不会干扰原始类代码的保存名称。 _save可能不够好,但你明白了。

更新:我更新上面的代码,使用指向原始函数的字符串变量。我认为这就是OP想要的。

由某些库定义的原始代码

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

现在我们使用func string变量指向该函数并执行它。

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

答案 1 :(得分:0)

我认为你这样做太复杂了。 如果您只能在doMyFunctiondoSomeOtherFunction之间进行切换,则可以在某处创建一个标记,告诉您在if语句中使用其中一个时使用其中一个。

如果你想调用一个你事先不知道的名字的函数而你只在运行时得到一个名字,你可以接受函数作为参数调用或接受函数的名称作为参数和调用它是这样的:var retVal = window[functionName]();(假设functionNamewindow对象的属性)。

我强烈建议直接接受函数作为参数,因为函数可能无法在全局范围内定义。

编辑: 在你澄清之后,我想,我可以给你一个满意的答案:

如果你有一个像var functionString = "function updateFunc(whatToUpdate){var retVal = doMyFunction(whatToUpdate);}";

这样的字符串

您可以使用Function对象定义函数: window.updateFunc = new Function("whatToUpdate", "return (" + functionString + ")(whatToUpdate)"); 这将替换现有的函数,只要您知道并指定参数,就可以为其提供所需的任何有效函数字符串。

答案 2 :(得分: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);
    }
})();

我强烈建议不要使用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);

<强>更新

此代码段适用于您的原始代码:

  <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错误。

答案 3 :(得分: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();

答案 4 :(得分: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'