What's the Best Approach?

Using JavaScript's public description, or the generic default interface description approach, doesn't limit your power in any way. In both cases, you'll be able to make your properties and methods callable outside the scriptlet. However, there are a few points to consider carefully before deciding which way to go.

To explain the difference between the two possibilities it is helpful to compare them with the usual ways of exporting functions from Windows DLLs. Since you might not be an expert Windows programmer, we'll briefly recall the key facts.

There are two ways to export functions from within Windows DLLs and make them visible to external callers, such as Visual Basic or other C/C++ programs. The first one requires you to create the so-called Definition Module File: a text file with a standard .def extension. DEF files list by name, and sometimes by number, all the functions that the DLL wishes to export. What you have to do is just write your functions and link the appropriate DEF file to the project. At any time you can consult the list of exported functions just by opening that given file.

The other way avoids using additional files. By adding a special keyword to the function's prototype you can make it self-exportable. That is, the compiler somehow signals those symbols to the linker, which will automatically put them into the appropriate export section of the final executable. If you want to know about the functions your DLL actually exports then you need to inspect all the source files that form the project.

Why You Should Use the Public Description

The JavaScript's public description is quite similar to a DEF file. It allows you to have a single place in your code where the entire automation interface is described. If you need to add a new property or method, just drop a new line in the scriptlet constructor and write the function. At any moment in time you can find out, easily and quickly, how many, and above all what, attributes your scriptlet is exposing.

But there is much more. JavaScript's public description is far more flexible.

In fact, it allows you to distinguish between internal and external names. You can have a Paint method implemented internally with a function called GiveItTheNameYouWant(). This is an important feature. I dare say it is a bit more important than the possibility of giving your dog's name to a poor innocent function. This feature makes it easier to maintain your scriptlet's code. Suppose that, at a certain point, you want to enhance the behavior of a method; say Paint. You write your new function, assign it a name that makes sense to you (say, DoPaintEx) and just modify the reference which the this.Paint attribute points to. To comment it out, just revert your changes in the constructor. There's no need to change even a single byte in any of the two internal versions of the same method.

Why You Should Use the Default Description

The default description approach looks like using the keyword _export, or rather _declspec(dllexport), to export functions from within a Windows DLL. You must have a perfect match between the externally callable name of your properties and methods, and the name by which they're implemented.

If you want to expose a method called Paint, then you absolutely must define a public_Paint subroutine and have it implement the desired behavior. You cannot choose a different name. However, you could maintain public_Paint as an outer wrapper of code and internally invoke another function.

<script language=VBScript>
Sub public_Paint()
  DoPaint 
End Sub
</script>

If you organize your code this way, you can easily obtain almost the same flexibility as the previous approach. In fact, the above code is logically equivalent to the following:

<script language=Javascript>
function CreateOurFirstScriptlet() {
  this.Paint = DoPaint;
} 
</script>

Of course, in this case we've obtained manually what is offered for free by Javascript's public description.

The default interface description does allow you to save some lines of code, but there does not exist a single place where all the interface attributes are gathered together.

Overall, What's Better?

Taking such a decision is pretty similar to picking good dishes from a restaurant menu. First you consider what the chef recommends—possibly consulting the waiter for more details—and then you make up your mind. In this case, the chef (that is, Microsoft) recommends JavaScript's public description approach. The waiter (us) attempts to explain some details about the choices. The rest is up to you. Overall, however, JavaScript's public description approach seems superior.

What If I'm Using Both?

What happens in the remote case in which you attempt to use both the approaches? Simply, the JavaScript approach takes precedence over the other. Suppose, for example, you're writing the following code:

<script language="JavaScript">
public_description = new CreateOurFirstScriptlet;
function CreateOurFirstScriptlet() {
  this.get_Image = DoGetImage;
  this.put_Image = DoPutImage;
  this.Paint = DoPaint;
}
function public_DoSomething() {
  // do something, possibly useful!
  return 1;
}
</script>

We have a public constructor that exposes the well-known Image property and Paint method. In addition, there's also a public_DoSomething method. What happens if you insert this scriptlet in an HTML page, and from there (or from a Visual Basic form) attempt to call Image or Paint? Everything works fine. And what happens if you call DoSomething? Then a nice error message will inform you that Internet Explorer 4.0 is unable to find the property or the method with that name.

If a public_description object is present, then Internet Explorer 4.0 ignores all the other functions that might have been declared public via the default interface description. Consequently, if you choose the latter approach, make sure you remove from your code any object called public_description.

© 1997 by Wrox Press. All rights reserved.