I want to check if the window.sessionStorage object exists. Is this the way to do it:
if (window.sessionStorage)
in javascript?
if(sessionStorage.length == 0) {
//do something
}
That will validate whether sessionStorage is empty or not. Alternatively, you can use this:
if(typeof(sessionStorage) == 'undefined') {
//do something
}
Use can use modernizr to check session/web storage and other browser features.
In case you can't add the lib, check how they handle it here
Cheers.
Your proposed solution will work since we know that the sessionStorage property must refer to an object—and objects always resolve truthy in expressions.
However a word of caution, when checking for the existence of any arbitrary property in JavaScript (where we don't necessarily know the value), it's safest to check that the key exists in the object of interest. For example:
var exists = (someObject && 'someProp' in someObject);
We need to do this because someProp could be a valid property yet the test would fail when equal to: false, "", 0, or any other value that would be falsey in an expression.
Related
I've seen before that undefined semantically should only be used for variables that have been declared but not defined, and if a variable should at any point be set or unset, I should initially set it to null and check the variable against null rather than setting it back to undefined.
I'm wondering about the case where I am checking something that should be undefined, as in the case I am checking what an unset key in an object points to
i.e.
var eva = {'asuka': 2, 'rei': 0};
if I were to check eva['shinji'], I would have to check for undefined, because there are cases where I would not know all the possible keys that would be checked against.
I guess in this case, eva['shinji'] being undefined would be correct, though in the specific case of keys in objects, using ('shinji' in eva) would be best?
However, I have a feeling there may be other cases where objects that were unknown were checked against, that I could not use a 'in' for instead, but the case of object keys was most apparent to me.
In those cases, would it be best to check for undefined?
First of all, your statement is incorrect, should be:
var eva = {'asuka': 2, 'rei': ''};
Then you can find eva['asuka'] or eva.asuka will give 2.
If you want to check if a property inside an object.
There are multiple ways to do that.
You can simple check eva && eva.hasOwnProperty('asuka')
eva && typeof(eva.asuka) !== 'undefined'
3.
var found = false;
for (i in eva){
if (i == 'asuka') {
found = true;
break;
}
}
As mattclemens commented, if you do not understand the differences and best practices surrounding undefined vs null please check out the link he posted, or one of the other multitudes of blog/forum posts, books, or videos regarding this subject (i.e. duckduck something like "js best practices undefined null").
Based on the first paragraph of your question it seems you have a grasp on what they mean, and this question comes down to context...
I'm wondering about the case where I am checking something that should be undefined...
This seems like a loaded question to me. What does "should be undefined" mean? This tells me that your code never sets that property that "should be undefined" and you are assuming nothing else is setting it. But really, "should be undefined" doesn't make sense to me. You either know it's not because it's never been outside the current scope and you haven't defined it yourself, or you don't know and it's best practice to check whether it's defined before checking if it's null.
So I see this as 2 basic scenarios:
Internally/Privately created and used exclusively internal to code you control
Externally/Publicly created or crossing the public/private line
1. Internal/Private use only
In the first scenario the answer is simple: initialize the object with default values (falling back to null) for all properties that will ever exist on the object...
var eva = {'asuka': 2, 'rei': null};
...or since you have direct control over the object throughout its lifecycle, add properties explicitly as needed using the default operator...
eva.shinji = eva.shinji || null;
Then whenever you need to check the value of a specific property, your only concern is whether it is null. You will notice this strategy being employed in some of the most widely used js libraries, such as jQuery, where internal variables are only ever checked against null, or even assumed to exist within some contexts.
2. External/Public use at any point in the object's lifecycle
For objects you can't trust there are two approaches I would suggest, and which one is choosen depends, again, on the details of the context. If you are receiving some object, and will be using that object repeatedly or modifying the data you receive from it for internal use only, or if it is unsafe to change the value of the original object in any way, you may want to make your own copy of the object and then deal with that copy exclusively. Again, this is illustrated in libraries/frameworks, such as jQuery and AngularJS, where things like window and the undefined value itself, are passed in to the IIFE, and an internal copy is created/extended for internal use throughout the lifetime of the consumer.
However, this may be unnecessary overhead for your situation. Instead you could just verify the contents of eva when it crosses that external/internal boundary. The following example does so with the default operator.
function yourFunction(eva) {
eva = eva || {};
eva.asuka = eva.asuka || 2;
eva.rei = eva.rei || null;
}
Alternatively, you may have a string value or array of string values that are keys you wish to verify exist on the object. In that case please consider the following example using Object.keys(). This example also allows for the array of names of keys to be undefined.
function foo(eva, keysToFind) {
eva = eva || {};
keysToFind = keysToFind || ['asuka', 'shinji'];
var keysToCheck = Object.keys(eva);
for(var k in keysToFind) {
var keyName = keysToFind[k];
var keyIdx = keysToCheck.indexOf(keyName);
if(keyIdx == -1) {
eva[keyName] = null;
}
}
}
Finally, as RaymondM points out, you can take this a step further if you need to determine whether a property was added to the object literal, it's prototype, or inherited from a super/base class...
You can simple check eva && eva.hasOwnProperty('asuka')
Again, taking context in to consideration, if you have already identified the context as scenario 1 or 2 from above, and are checking any more than a single property's existence, then it will likely be more efficient to check for === null or typeof eva.asuka === 'undefined', respectively. Or even check if(eva && eva.asuka) { ... }, if you're certain asuka has been defined.
In the code below, I can't just do o.property.startsWith because there's a chance that o doesn't have a property called property on it. So I have to do this check everytime.
if (o.hasOwnProperty('property')) {
console.log(o.property.startsWith('hello'));
}
Is there a simpler or less repetitive way of accessing a sub-property of a property that may not exist?
How about just:
console.log((o.property || "").startsWith('hello'));
If you are planning on using this validation many times, you could add it to a function to prevent code duplicates:
function validateProperty(property, startsWith) {
return property && property.startWith(startsWith);
}
console.log(validateProperty(o.property, 'hello'));
console.log(validateProperty(o.property2, 'bye'));
Plus, it might interest you to know that the sub-properties can be accessed via brackets:
o.property === o['property']
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.
Currently I check if sed object already exists as to not wipe it if it does, then create the object.
if (typeof result === 'undefined') {
results = {};
}
It's just that I come from using PHP where you don't really have to declare things as much as you do in JS.
Though I tend to use JS objects as I use arrays in PHP, as a way to temporarily store information which I need to access further down in a script.
you could do:
var results = window.results || {};
This wouldn't work if certain values (e.g., 0, null, or false) should not be overwritten, but:
results = results || {};
This works because || returns the first value if it is truthy or the second otherwise. undefined, along with some other values partially listed above, are falsy, but objects are truthy.
Just write your code so you never have to guess. Avoid globals, don't create variables conditionally, set defaults early. You should only need your pattern in special cases, like writing a library for third parties, using a module system, etc.
I'm currently in the creation of a javascript function library. Mainly for my own use, but you can never be sure if someone else ends up using it in their projects, I'm atleast creating it as if that could happen.
Most methods only work if the variables that are passed are of the correct datatype. Now my question is: What is the best way to alert users that the variable is not of the correct type? Should one throw an error like this?
function foo(thisShouldBeAString){ //just pretend that this is a method and not a global function
if(typeof(thisShouldBeAString) === 'string') {
throw('foo(var), var should be of type string');
}
#yadayada
}
I know that javascript does internal type conversion, but this can create very weird results (ie '234' + 5 = '2345' but '234' * 1 = 234) and this could make my methods do very weird things.
EDIT
To make things extra clear: I do not wish to do type conversion, the variables passed should be of the correct type. What is the best way to tell the user of my library that the passed variables are not of the correct type?
The problem with type checking is that its actually quite hard to do. For example:-
var s = new String("Hello World!");
alert(typeof s);
What gets alerted? Ans: "object". Its true its a daft way to initialise a string but I see it quite often none-the-less. I prefer to attempt conversions where necessary or just do nothing.
Having said that in a Javascript environment in which I have total control (which is not true if you are simply providing a library) I use this set of prototype tweaks:-
String.prototype.isString = true;
Number.prototype.isNumber = true;
Boolean.prototype.isBoolean = true;
Date.prototype.isDate = true;
Array.prototype.isArray = true;
Hence testing for the common types can be as simple as:-
if (x.isString)
although you still need to watch out for null/undefined:-
if (x != null && x.isString)
In addition to avoiding the new String("thing") gotcha, this approach particularly comes into its own on Dates and Arrays.
Some small remarks on type checking - it's actually not that complicated:
Use typeof to check for primitives and instanceof to check for specific object types.
Example: Check for strings with
typeof x === 'string'
or
typeof x === 'string' || x instanceof String
if you want to include string objects.
To check for arrays, just use
x instanceof Array
This should work reasonably well (there are a few known exceptions - eg Firefox 3.0.5 has a bug where window instanceof Object === false although window.__proto__ instanceof Object === true).
edit: There are some further problems with detection of function objects:
In principle, you could both use typeof func === 'function' and func instanceof Function.
The catch is that in an unnamed browser from a big corporation these checks return the wrong results for some predefined functions (their type is given as 'object'). I know of no workaround for this - the checks only work reliably for user-defined functions...
edit2: There are also problems with objects passed from other windows/frames, as they will inherit from different global objects - ie instanceof will fail. Workarounds for built-in objects exists: For example, you can check for arrays via Object.prototype.toString.call(x) === '[object Array]'.
Libraries like jQuery do not inform the user of the error.
If a function is expecting a number, and a user passes a string, the function just returns without doing anything.
That way, you will avoid JavaScript errors popping up on a live website.
PS. Just make sure to always type check your inputted parameters, to avoid JavaScript errors being thrown.
How about throw:
https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Statements/throw
Also type of does not distinguish between Array, Null, Object very well. Look at the funciton here: http://javascript.crockford.com/remedial.html, plus there are a few other ways to do it.
Personally I would not do the type checking since it is a step that will just add more processing time to the code. If you care about performance, you would want to chop off as many milliseconds of processing time as possible. Good Documentation will cure the need for the check.
What's about just to silently convert string to numeric datatype on function startup?
You always can determine the datatype of 'string'. Can't you?
You could check for some value like "debug=1" set. If there is - you could output errors like alerts. So in development mode user will see them, but on real site he will turn it off. Same way browser will not show you error message - you need to look at JS console.
Also there is FireBug. You could detect that and put FB debug Messages also.