Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force JavaScript exception/error when reading an undefined object property?

Tags:

javascript

I'm an experienced C++/Java programmer working in Javascript for the first time. I'm using Chrome as the browser.

I've created several Javascript classes with fields and methods. When I read an object's field that doesn't exist (due to a typo on my part), the Javascript runtime doesn't throw an error or exception. Apparently such read fields are 'undefined'. For example:

var foo = new Foo(); foo.bar = 1; var baz = foo.Bar; // baz is now undefined 

I know that I can check for equality against 'undefined' as mentioned in "Detecting an undefined object property in JavaScript", but that seems tedious since I read from object fields often in my code.

Is there any way to force an error or exception to be thrown when I read an undefined property?

And why is an exception thrown when I read an undefined variable (as opposed to undefined object property)?

like image 354
stackoverflowuser2010 Avatar asked Jun 28 '11 18:06

stackoverflowuser2010


2 Answers

This can be achieved using ES6 proxies:

function disallowUndefinedProperties(obj) {      const handler = {          get(target, property) {              if (property in target) {                  return target[property];              }                throw new Error(`Property '${property}' is not defined`);          }      };        return new Proxy(obj, handler);  }    // example  const obj = { key: 'value' };  const noUndefObj = disallowUndefinedProperties(obj);    console.log(noUndefObj.key);  console.log(noUndefObj.undefinedProperty); // throws exception
like image 54
P. Meller Avatar answered Sep 24 '22 21:09

P. Meller


This looks to me like a classic case of trying to shoehorn one language into the paradigms of another - better IMHO to change your coding style to follow how Javascript does things than try to make it conform to C++ concepts and expectations.

That said, if you want to throw an error as you suggest, you'll need to define some sort of custom getProperty function, either on the object you're trying to access or in the global scope. An implementation might look like this:

function getProperty(o, prop) {     if (o.hasOwnProperty(prop)) return o[prop];     else throw new ReferenceError('The property ' + prop +          ' is not defined on this object'); }  var o = {     foo: 1,     bar: false,     baz: undefined };  getProperty(o, 'foo'); // 1 getProperty(o, 'bar'); // false getProperty(o, 'baz'); // undefined getProperty(o, 'foobar');  // ReferenceError: The property baz is not defined on this object 

But this is ugly, and now you've got this custom language construct in all of your code, making it less portable (if, for example, you wanted to copy any part of your code into another script, you'd have to copy your new function too) and less legible to other programmers. So I'd really recommend working within the Javascript paradigm and checking for undefined before accessing the properties you need (or setting up your code so that false-y values are expected and don't break things).

As to your second question, why Javascript throws an error for undefined variables but not for undefined object properties, I can't give any better answer than "Because that's what's in the language specification." Objects return undefined for undefined property names, but undefined variable references throw an error.

like image 42
nrabinowitz Avatar answered Sep 25 '22 21:09

nrabinowitz