Stop object instantiation in javascript when conditions not met - javascript

I have a custom object that takes a jQuery object as an argument. What is the best way to handle stopping the instantiation of the object if an invalid datatype is passed.
var MyObj = function( $obj ) {
if( ! ($obj instanceof jQuery) )
return false // This is where it should cancel or error or something
}
var myInstance = new MyObj( 'invalid' );

I guess the best way to tell the user that something is wrong is to throw a new error like that :
throw new Error('Wrong object type');
But it really depend on your goal.
Example, jQuery doesn't trow an error when you pass invalid argument to his constructor, it just return an empty object and the code continue.
After seeing Cal Markham answer, i am a little bit confused about your question.
If your are looking why your code doesn't work, just comment and ill delete that answer since it does answer your current question.

The best way to handle an exceptional situation depends on the particular circumstances of your code. In some cases, when you have the option, you can continue execution in a non-surprising way. In others, when you can't return a meaningful object, you should throw an error. The best guideline is that your code shouldn't surprise the person using it.
An example of an exceptional situation handled in a non-surprising way is in jQuery:
$('#myDiv').css('color', 'red');
Suppose that there is no #myDiv, you could throw an error to alert the developer that he's trying to change the color of an inexisting element. Or you could silently ignore it. jQuery chose the second option and made it work in a coherent, non-surprising way.
The advantage of throwing errors sooner is that the developer needs less time debugging when something goes wrong. The disadvantage is that the code will probably be messier.

The code you have would work fine, just a little syntax error for instanceof. It should be
if( ! ($obj instanceof jQuery) )

Related

Checking object exists before getting property in JavaScript

I'm working on some existing code that looks something like this:
return this.getMyObject() && this.getMyObject().myArray[0];
As far as I can tell it is checking that the object returned by getMyObject() exists before returning the first item in it's myArray property. How does this work and is it good form?
Update: The reason for my question came from the confusion over how the && operator can be used to return a property value and not a boolean result. After further thought, to make it more readable I refactored the line to:
return this.getMyObject() ? this.getMyObject().myArray[0] : undefined;
Obviously I am assuming here that the myArray property will exist.
That code works because of type coercion. Some people will tell you its good and some people will say always truly check something using typeof
if (typeof someVariable === 'undefined')
Even in examples below the above check isn't enough. I don't know what is better but that code as far as I am concerned isn't how I write it myself but it is accepted with a lot of javascript developers. There are times that code in the correct conditions can still pass the first check and yet throw an error accessing the property. Depends how controlled your situation is that determines, to me, if you should or shouldn't allow it.
Example of passing first check and failing:
var myObject = 1;
var test = myObject && myObject.myArray[0];
Or as #JamesThorpe pointed out in comment above:
var myObject = {};
var test = myObject && myObject.myArray[0];
Also people familiar with some coding languages but not JS might look at that code and not understand what it means where checking with an if and then returning the value might be a bit more readable to others, which is also a plus I think.
It's correct form. If there is no object returned by this.getMyObject() then function will return false in another case second part of condition will be executed and returned as a result of function. It's good practice to check if object exists before calling any method on it, because an error could occur if not to do so.
But you should check an existence of an object only if you are not sure whether it exists.

What does this javascript code means?

I'm working on a form that does changes on the fly and I'm trying to understand it better.
nonetheless, I came upon and input that has this and I was wondering what does this statement means any example would be appreciated. Thank you
onclick="if(this.onchange){this.onchange();}"
This is checking to see if this has a function defined as onchange. In javascript, you don't need if (this.onchange != null). If the value is null, undefined, or has an empty string, the value in the if statement returned is false. This is usually a good practice to avoid null reference errors in javascript when you aren't positive that every browser is going to support whatever you're attempting to use. (or other reasons I'm missing now)
For example, when adding a line to output to the console in Google Chrome...
console.log("output here");
This may cause errors in other browsers if I remember correctly. A good way to handle this would be to use:
if (console) { console.log("output here"); }
In simple terms,
"If this element has function associated to it's onchange event listener, execute it.".
It's a way to check if it is declared
if (typeof this.onchange != "undefined"){
this.onchange();
}

Throw an error if a JavaScript value is not of a certain "class"?

is there a way to check the type of an object in javascript against a custom type? I probably worded that wrong so let me show you what i'm wanting to do:
if(typeof value == "MyClassType")
console.log(true);
can you do this with typeof, instanceof, or anything like that? I'm wanting to throw an error if the user provides a value that's not a class i'm expecting.
Use the instanceof operator:
if (!(value instanceof MyClassType)) {
throw new Error("expected object of type 'MyClassType'");
}
Documentation: msdn, mdn
In javascript, you shouldn't really care if an object is a particular type. What you should care about is whether is has the methods that you expect. In fact, it should be OK to provide any object as long as that object has the appropriate methods on it that implement the expected behavior for those methods. That's one of the beauties of javascript. It isn't hard types and doesn't need to be. Heck look at the jQuery model. They make a jQuery object support the methods of an array so it can be used in place of an array in most situations even though it's not technically just an array.
So, I'd suggest that you should test the object to see if you see a few of the expected and needed methods on it and if you find them, then merrily proceed. If you don't find the methods you need, then throw an error. This will catch the general misuse issues right away while not overconstraining how a client might use the API.
You can test for the existence of a method/property with nothing more than this:
if (obj.makeQuackSound && obj.flySouthForWinter) {
// must be a duck
}
If you want to check if they were actually functions, not just properties, you could do that too.

How can I ensure that all of my JavaScript functions return a value?

I've had numerous bugs happening just because of a missing return in a function. You see, when most of the code you write is in Ruby, it's easy to forget about explicit returns.
So I'd like to use something similar to JSlint (which I already use) to check that all functions return something. Yes, I think it's better to explicitly return something when it's not required than to hunt down missing returns.
So, are there any tools that would check for returns? Or maybe I can assert it in runtime in a simple manner?
Please don't suggest Coffeescript, I'm aware of its existence.
JSUnit example:
<script language="javascript" src="jsUnitCore.js"></script>
<script language="javascript">
function testWithValidArgs() {
assertEquals("someFunction should return something", "Expected REturn Value", someFunction(2, 3));
}
</script>
Just add return consistently. But to be honest, JSlint is a VERY strict checking tool. You will never get errors if you're not returning values unless you're trying to define a variable using the response of a function, but in that case it's more than logic that you add a return statement.
However, if you're still dedicated to have a return statement in every function, you should add them from the start. There is no tool that adds them.
I'm not aware of any tools that will do this out of the box. But it would not be hard to write one.
Start by using UglifyJS to parse your code into a syntax tree. Write a recursive function that examines all code, looking for function definitions. For every function you find, look at the last statement. If that one is not a return-statement, then print a warning.
(Too long for comment.)
My problem with returning something when a function has no (meaningful) return value is that it's misleading, unless it returns undefined, which defeats the purpose.
If I see a return, I have to reason about the code both in the method and at the call site.
In the function I have to determine if it ever returns anything else, why it returns the value it does, etc. The only real way around this is to return a constant that makes it obvious the it's not really returning anything, it's just to satisfy a desire to return something.
At the call site, if a return value is ignored, I need to understand why, and if it's okay to do so. If I know every function returns something, I then have to check the function to see if it's returning that special value, or go through the above process.
I'd almost rather namespace my functions into "function" and "method" namespaces at that point as a differentiater. This would allow automated testing of each namespace to make sure that all functions return something useful, all methods specifically don't, and would provide a source-level clue as to which the caller should expect.

Using try-catch to retrieve the value of nested property. Is it an valid approach?

We have an object (referenced by data) and we want to retrieve the value of a nested property. Ideally, we would like to do it like so:
value = data.category3.section2.article4.title;
We cannot do this like so, because the above line throws a reference error if any of the mediate objects (category3, section2, or article4) are not defined (at the corresponding positions) inside the data object.
Now, to nullify any potential reference errors that might be thrown, we could just place the above line inside a try-catch statement:
try {
value = data.category3.section2.article4.title;
} catch (err ) {}
This works! However, I am not confident that relying on try-catch in such a way is a good practice. The alternative solution would be to manually traverse to the desired property value. I have written a compact utility function that accomplishes that:
function get( val, names ) {
names = names.split( '.' );
while ( val && names.length ) { val = val[ names.shift() ]; }
return val;
}
Now we can get the property value like so
value = get( data, 'category3.section2.article4.title' );
So, my question is:
Is the try-catch approach a valid solution? Or are there valid reasons why it should be avoided?
Btw, the try-catch approach is heavily biased in this thread: What's the simplest approach to check existence of deeply-nested object property in JavaScript?
Why not:
var value = data &&
data.category3 &&
data.category3.section2 &&
data.category3.section2.article4 &&
data.category3.section2.article4.title;
That is safe (if any of the objects in the traversal chain are not set, value will be null). That is a little neater than a bunch of if blocks, and avoids (?mis)using exceptions.
Another use of that method to provide a default value on failure:
var value = data &&
data.category3 &&
data.category3.section2 &&
data.category3.section2.article4 &&
data.category3.section2.article4.title || 'default value';
Both are fine. The only major differences between them I can think of are that
The try-catch may cause a debugger to unecessarily halt too often if you tell it to stop on all exceptions.
This is relevant you need to debug code that is swallowing exceptions. For example, some promise libraries wrap all callbacks in a try-catch block.
The string splitting version can't easily cope with properties that contain a dot in them
var x = {'.': {a: 17}};
try{ obj['.'].a }catch(e){}
get(/*???*/)
If you want something robust that avoids both pitfalls I would suggest a function that can (at least optionally) directly receive a list of properties.
get(val, ['prop1', 0, '.', 'category2']);
I think the differences here are going to be mostly contextual - it depends on the data you're trying to access and what you want to do with it.
For example, the second function will return equivalent undefined values for a variety of circumstances, including both data.category3 === undefined and data.category3.section2.article4.title === undefined. Using try/catch here tells you that you have an actual traversal error, rather than a property that hasn't been set, which you might want to handle differently.
Abusing try catch like this is a dirty hack.
Try catch is there to catch exceptions you throw. Exceptions are used for exceptional cases.
In this case both cases are wrong. You should never have to traverse data.category3.section2.article4.title; where every step can fail.
You should simply be able to assert that if data has a category then it should have a section, article and title.
I say refactor the code so you don't have multiple levels that can fail.
I have seen the answers here and I think that the traversing is your best move, but it looks quite bothersome. You can make a function that traverses it for you or you can use the almighty brototype library found at: https://github.com/letsgetrandy/brototype
This way you can do something like this:
if (Bro(data).doYouEven('category3.section2.article4.title')) {
value = data.category3.section2.article4.title;
}
or you can use a callback:
Bro(app).iDontAlways('category3.section2.article4.title')
.butWhenIdo(function(title){
value = title;
});
I think everyone should check this amazing library out, and code with great bro-ness.
If you dislike the brototype, you can indeed use your own get function.

Categories

Resources