Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No-argument method on window.external is invoked when checking with typeof

I am trying to display an HTML page with embedded JavaScript code inside a System.Windows.Forms.WebBrowser control. The JavaScript code is expected to interact with the embedding environment through the window.external object. Before invoking a method on window.external, JavaScript is supposed to check for the existance of the method. If it is not there, the code should invoke a generic fallback method.

// basic idea
if (typeof(window.external.MyMethod) != 'undefined') {
    window.external.MyMethod(args);
} else {
    window.external.Generic("MyMethod", args);
}

However, checking for a no-argument method with typeof seems to invoke the method already. That is, if MyMethod accepts any positive number of arguments, the code above will work perfectly; but, if MyMethod is a no-argument method, then the expression typeof(window.external.MyMethod) will not check for its type but invoke it, too.

Is there any work-around to this behavior? Can I somehow escape the expression window.external.MyMethod to prevent the method call from occurring?

like image 349
janko Avatar asked May 09 '10 14:05

janko


1 Answers

I have not debugged your exact situation but I believe my psychic powers can work out what is going on here.

The JScript language makes a distinction between use of a function and mere mention of it. When you say

x = f;

that says "assign a reference to the function identified by f to the variable x". It mentions f. By contrast,

x = f();

uses f. It means "call the function identified by f and assign the returned value to x."

In short, functions in JScript are essentially what we would think of as properties of delegate type in C#.

Some languages do not make this distinction. In VBScript, if you say x = f and f is a function, that means to call the function, same as x = f(). VBScript does not make a strong distinction syntactically between the use and mention of a function.

The way this is all implemented is we use COM; specifically, we use OLE Automation. When dispatching a field of an object to get its value, the JScript engine passes flags that mean either "property get" or "method invoke", depending on whether it was use or mention.

But suppose your object being dispatched was written with the expectation that it would be called from VB. Perhaps it was written in VB. It is perfectly reasonable and legal for a VB object to say "oh, I see you're asking me for the value of this method. Since I don't understand the difference between mentioning a method and using it, I'll just invoke it no matter which flag you pass".

I don't know if there is a workaround, but I'd be willing to bet as much as a dollar that what's happening is the invoked object is assuming that the caller wants VB semantics.

like image 149
Eric Lippert Avatar answered Nov 09 '22 18:11

Eric Lippert