JScript tips

Using JScript Objects to Implement Shared Constants

The question has come up in the past: how can you define constants in JScript that you can reference in multiple scripts (without resorting to using the evil eval).

 

In the past I’ve ended up copying/pasting the same code into multiple scripts that had the same constants (see “Bad Approach” below).

 

I played around with this a bit when I made changes to the infrastructure to support multiple products and I found a nice way to handle this.

 

Example

In this example, we are using strings like “iis”, “iisexpress”, etc. to determine what “mode” we are in, i.e. what product we are testing. This is passed to the driver, to run.js and stored as ScriptUtil.TargetProduct so that scripts themselves can change behavior based on.

 

Bad Approach

So, one non-ideal way to deal with this is have a bunch of local constants:

 

    var PRODUCT_IIS = "iis";

    var PRODUCT_IIS_EXPRESS = "iisexpress";

    var PRODUCT_MSDEPLOY = "msdeploy";

 

And now in every script that needs to check the TargetProduct would have to duplicate this code so it can do something like:

 

    if (ScriptUtil.TargetProduct == PRODUCT_IISEXPRESS)

    {

        // do some IIS Express specific stuff...

    }

 

(or worse, just hardcode "iisexpress"…no, don’t)

 

Good Approach

So I’d like to create a group of related constants (to be sort of used like an enum in this case but that's not the only reason to use this approach) that I can access from any other script or scriptlet. Here’s how:

 

First I add a read-only property to expose the enum:

 

      <property name="PRODUCT">

        <get/>

      </property>

 

Now during initialization I set the property to a new object:

 

var PRODUCT = new Object();

PRODUCT.IIS         = "iis";

PRODUCT.IISEXPRESS  = "iisexpress";

PRODUCT.MSDEPLOY    = "msdeploy";

PRODUCT.WEBPI       = "webpi";

 

(Yes, at runtime I can just add as many properties as I need to my JScript object)

 

Now, any script that instantiates ScriptUtil can reference these strings, like so:

 

    if (ScriptUtil.TargetProduct == ScriptUtil.PRODUCT.IISEXPRESS)

    {

        // do some IIS Express specific stuff...

    }

 

And even cooler, I can iterate all these strings in my object without knowing anything about them. For example, in run.js I need to ensure that the product string passed in is valid:

 

    // iterate thru known products to validate the one passed in

    // (stored as runOptions.ProductType)

    var IsValidProduct = false;

    for(p in ScriptUtil.PRODUCT)

    {

        // iterating this way gives you property names of the object,

        // and you can use them as a key to get the value for each

        // property. For example ScriptUtil.PRODUCT[“IIS”] returns

        // “iis”

        if(ScriptUtil.PRODUCT[p] == runOptions.ProductType)

        {

            IsValidProduct = true;

            break;

        }

    }

 

    if (!IsValidProduct)

    {

        WScript.Echo("Error: Invalid product passed in on command line!");

        PrintUsage();

    }

    else

    {

        // save the current product being tested (note this now serves to put

        // us in "IISExpressMode" (or whatever mode))

        ScriptUtil.TargetProduct = runOptions.ProductType;

    }

發佈了40 篇原創文章 · 獲贊 8 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章