0

How can I throw an exception using a variable within the exception name during the throw new statement?

I have a list of exceptions that I'm trying to throw depending on whether or not one variable is zero in length. The name of the exception, for example, contains the variable name.

Works

if (X.length === 0)
{
    throw new NoXException();
}

if (Y.length === 0)
{
    throw new NoYException();
}

if (Z.length === 0)
{
    throw new NoZException();
}

Doesn't work

var X = 'Oh';
var Y = 'Hai';
var Z = '';

// Contains "NoZException"
var ex = "No" + ((X.length != 0) ? ((Y.length != 0) ? 'Z' : 'Y') : 'X') + "Exception";

// Throwing ex gives an error
throw new ex();
Jimbo
  • 25,790
  • 15
  • 86
  • 131

1 Answers1

4

You are trying to convert a string to a function and create a new instance of a variable, which won't work.

There are ways to get a function corresponding to a string: How to turn a String into a javascript function call?

But a better way to go about this would be to simply do the first if statement, or convert it to a switch.

For a global variable:

// Set up in global scope, not in the scope of something else.
var NoXException = function () { ... }

var variable = "No" + getMissing() + "Exception";
throw new window[variable]()

For a variable that's stored within another's scope:

var exceptions = {}
exceptions.NoXException = function () { ... }

var variable = "No" + getMissing() + "Exception";
throw new exceptions[variable]()
// Alternatively
throw new window['exceptions'][variable]()
Community
  • 1
  • 1
Blam
  • 2,888
  • 3
  • 25
  • 39
  • The `NoXException`, `NoYException` and `NoZException` classes exist though? – Jimbo Jul 11 '13 at 11:12
  • But simply creating a string won't convert that string into that corresponding class. You can do a look up as the link in my answer shows, using `window[ex]`. – Blam Jul 11 '13 at 11:13
  • Couldn't get it working: [fiddle](http://jsfiddle.net/B859C/). – Jimbo Jul 11 '13 at 11:15
  • @Jimbo: That's because `NoZException` is not global in your example. All the code is *local* to the `load` event handler. If you want the code to be global, select `No wrap` in the settings. – Felix Kling Jul 11 '13 at 11:16
  • Could you please provide an example to make your comment work? Although marked as a duplicate, I can imagine other's finding this post useful with "exception" being in the name, even if they are just functions ;) Stuck here: http://jsfiddle.net/B859C/2/ – Jimbo Jul 11 '13 at 11:19
  • http://jsfiddle.net/B859C/3/ Now that you have a variable defined, you can look up the exception using the variable as an array. `class['attribute']` – Blam Jul 11 '13 at 11:21
  • Perfect! Cheers @Blam - want me to add this to your answer so I can mark it as correct? – Jimbo Jul 11 '13 at 11:22
  • @Jimbo: Do you see the two select boxes on the left hand side? One says "onLoad". You have to select "No wrap - in " or "No wrap - in ". http://jsfiddle.net/B859C/4/. Have a look at the jsFiddle documentation: http://doc.jsfiddle.net/basic/introduction.html#fiddle-settings-sidebar. – Felix Kling Jul 11 '13 at 11:25
  • @FelixKling Ahh, great thanks. I'm actually going to be using non-global stuff within individual classes - OOP wasn't the focus of this ;) but your help is much appreciated, thank you! – Jimbo Jul 11 '13 at 11:27
  • @Jimbo: Good, I would not advice for global variables anyway ;) – Felix Kling Jul 11 '13 at 11:28
  • @Blam: FYI, the variable is not used "as an array". This way (`foo['bar']`) of accessing properties is called *bracket notation* (and is equivalent to *dot notation* (`foo.bar`)). It just happens that bracket notation is the only way to access array elements. I'm just saying this so that no one thinks this has anything to do with arrays (and confuses arrays and objects). – Felix Kling Jul 11 '13 at 11:30
  • You're right I just wasn't sure of the terminology, thanks :) – Blam Jul 11 '13 at 11:32