10

This one's a long shot...

In Javascript, I was accessing an object attribute that I was certain existed, but I had a typo was in the name of the key, so was returning undefined and creating a bug.

How can I write code equivalent to the following, but that throws an error because the key does not exist?

var obj = {'myKey': 'myVal'},
    val = obj.myKye;

I'm trying to find a solution that doesn't require me writing a wrapper function that I use every time I want to access a member of an object. Is it possible? Is there another, 'stricter' technique in Javascript for accessing object attributes?

Trindaz
  • 17,029
  • 21
  • 82
  • 111

5 Answers5

3

You can't...

If you want to be very careful hasOwnProperty will let you check if property is defined.

function GetSafe(obj, propertyName)
{
   if (obj.hasOwnProperty(propertyName)) return obj[propertyName];
   return "Unknown property:"+ propertyName; // throw or some other error reporting.
}
var obj = {'myKey': 'myVal'};
alert(GetSafe(obj, "myKey"));
alert(GetSafe(obj, "myKye"));
Alexei Levenkov
  • 98,904
  • 14
  • 127
  • 179
3

a solution that doesn't require me writing a wrapper function that I use every time I want to access a member of an object. Is it possible? Is there another, 'stricter' technique in Javascript for accessing object attributes?

No. You could use a Proxy, which is designed to do exactly what you want. Yet, it is only a draft and currently only supported in Firefox' Javascript 1.8.5 (FF18+).

There is no other possibility to have an implicit getter function for all property accesses. You will have to code it explicitly.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
1

Try this:

function invalidKeyException(message) {
   this.message = message;
   this.name = "invalidKeyException";
}

var obj = {'myKey': 'myVal'},
val = obj.myKye;
if (val == undefined)
    throw new invalidKeyException("Key does not exist.");

JSFiddle: http://jsfiddle.net/r2MM4/

(Look at the console)

Hanlet Escaño
  • 17,114
  • 8
  • 52
  • 75
0

You can try these ways:

1) Using typeof:

try {
    var obj = {'myKey': 'myVal'}, val;

   if(typeof (obj.myKye) === 'undefined')
   {
      var e = new NotImplementedError("NotImplementedError Your_message");
      throw e;
   } 
   else
   {
     val = obj.myKye;
   }    
    alert(val);
   }
catch(e) 
  {
    alert(e);
  }

2) Using obj.hasOwnProperty(prop):

try {
    var obj = {'myKey': 'myVal'}, val;

   if(obj.hasOwnProperty(myKye))
   {
     val = obj.myKye;
   } 
   else
   {
      throw 'Property undefined';
   }
    alert(val);
   }
catch(e) 
  {
    alert(e);
  }
Amol M Kulkarni
  • 21,143
  • 34
  • 120
  • 164
  • This is not completely correct - "undefined" is possible value (rare, but still): `obj={"myKey":undefined }` is valid object with `myKey` property. – Alexei Levenkov Jun 21 '13 at 05:52
  • 1
    :) it is exactly the same as before - `typeof(undefined)==="undefined"`, just longer. Side note `===` is better if you know that types must match (as in case of `typeof`). – Alexei Levenkov Jun 21 '13 at 05:57
  • @AlexeiLevenkov What is issue with `obj={"Key1":undefined }` and `typeof (obj.Key1) === 'undefined'`? doesn't it work fine? – Amol M Kulkarni Jun 22 '13 at 05:17
  • It does - also you can't check that property is not there this way - your recent edit to use `hasOwnProperty` should indicate that property is present, but value is `undefined`, unlike property not present at all. – Alexei Levenkov Jun 22 '13 at 07:02
-1

You can use a try-catch, hasOwnProperty and create a ReferenceError.

var obj = {
        'myKey': 'myVal'
}, val;

try {
    if(obj.hasOwnProperty(myKye))
    {
        val = obj.myKye;
        alert(val);
    }

    else{
        var ex =  new ReferenceError()
    }
}
catch(ex) {
    alert(ex);
}

Test Link

UPDATE:

obj.myKye returns undefined and doesn't throw an exception because,

That's the JS language specification.

Objects return undefined for undefined property names, but undefined variable references throw an error

painotpi
  • 6,894
  • 1
  • 37
  • 70
  • 1
    Not sure I follow this - The whole problem is that referencing obj.myKye *doesn't* throw an error. I'm trying to get it to throw an error, not handle errors. – Trindaz Jun 21 '13 at 05:41
  • Because that's the `JS` language specification. Objects return undefined for undefined property names, but undefined variable references throw an error. – painotpi Jun 21 '13 at 05:47
  • 2
    The OP asked for "how to throw an exception from this", and when you say "*you can use a catch statement*" this neither is correct nor answers the question. You fixed that now by giving the "it's impossible" answer, but the first is still wrong. Btw, you should not use the ES3 reference any more – Bergi Jun 21 '13 at 06:04
  • The downvote wasn't from me, but I imagine it's because the answer just doesn't apply to the question. – Trindaz Jun 21 '13 at 06:04