Overriding external object's function using Ja

2019-05-31 09:07发布

问题:

I am currently working on an IE-only project which makes use of an external object model provided by the host application. Internet Explorer allows access to this external object through browser components: http://msdn.microsoft.com/en-us/library/ie/ms535246(v=vs.85).aspx

Access to the object takes the form of JavaScript function invocations, similar to:

external.MethodName(arg1, arg2);

One of the recent changes to the application flow will introduce hundreds, if not thousands of if-statement conditionals around these JavaScript invocations, e.g.:

if (X) {
    external.MethodName(arg1, arg2);
} else {
    // do something else
}

Rather than modify potentially thousands of HTML files, it would seem to make sense if we could override or rewrite the external object's functions so that the if condition only appears in one place. Normally, this could be accomplished in JavaScript with:

external.OldMethodName = external.MethodName;
external.MethodName = function(arg1, arg2) {
    if (X) {
        external.OldMethodName(arg1, arg2);
    } else {
        // do something else
    }
};

However, this results in an "Invalid procedure call or argument" script error, because you cannot reference the external host method this way.

I do not have access to the host application proprietary code to change the external method directly.

Is there any way I can use JavaScript to override the external object's functions, or will I need to wrap the (potential) thousands of invocations with if-statements (a very bad practice)?

UPDATE: After much back-and-forth with the client, we have managed to reach out to the third-party vendor to update the external host method, which is vastly preferable to our method of wrapping the method on the front end. I have accepted Paul's answer in the meantime.

回答1:

Use toString() and eval:

var foo = external.MethodName.toString().replace("OldMethodName", "MethodName").replace("bar","baz");
eval(foo);
if(x) 
  { 
  external.OldMethodName(arg1,arg2);
  }
else
  {
  MethodName(arg1,arg2)
  }