Is there a better way to declare an object - javascript

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.

Related

What does "|| {}" mean at the start of a JavaScript file

I am looking at some JavaScript files. Some of them have something interesting at the beginning:
var something = something || {};
Where "something" is clearly a kind of varable name. What does this mean and what does it do? In fact, one file has this and nothing else.
This is a common pattern to make sure a variable exists and if it does not, to set it to a known initial value so it can be used later. In particular:
If the variable something already has a value that is not falsy, this line leaves the value of the variable unchanged.
If this variable something does not have a value, or is falsy, this line sets the value of the variable to {}.
You will see this pattern a lot when adding properties to an object in a script. Let's say you worked for the company Acme and you had a lot of script files to integrate with other people's code. The Acme object would have a bunch of properties and a bunch of functions. In some scripts you might want to add properties to the object. But you can't just say
Acme.TIMEOUT = 300;
at the top of a file because the variable might not exist. But if it does exist, you want to use the existing variable. If it doesn't, you need to create a fresh object first.
So
var Acme = Acme || {};
will guarantee it exists, and then you can use it.
Be careful with this, though. I don't like this pattern because in modern JavaScript (where we use let and const instead of var), having an undefined variable will cause an error to be thrown. You should say:
window.Acme = window.Acme || {};
if you are in a browser. The reason for this is that it makes clear Acme is a property of the window object. Referencing a non-existent property of an object is harmless, you just get undefined. But referencing a non-existent variable will throw an error in modern JavaScript (or if not, it should).
It's a default value for "something" variable.
So if something is not initialized, it will end up containing a blank object (the {}).
in other words something equals (sometging or {}) where undefined evaluates to false so {} is returned.

Javascript checking undefined semantics

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.

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.

Difference between `var options = options || {}` and `options || (options = {})`

I often use var options = options || {} as way to default to an empty object. It's often used to initialize an option object in case it's not passed in the parameter of a function call.
The thing is I've read in several places (blog posts, source code) that options || (options = {}) better express the developer's intent. Can someone elaborate on it? I don't see the functional difference between the two, so there's something I must be missing here.
--- edit
I saw in Backbone.js source code in several places, like https://github.com/documentcloud/backbone/blob/0.9.2/backbone.js#L273
I think I saw it too in jQuery's source code too. And in the multiple Js writing style guides that flourished.
--- edit 2 code example :
var func = function(param, options) {
// How I do it
var options = options || {};
// How I should do it in the "same" way
options = options || {};
// The "other" way
options || (options = {});
}
There's no real difference, assuming you meant:
function fn(options) {
// type a
options = options || {};
// type b
options || (options = {});
}
Mostly a matter of preference, I think (a) is a whole lot clearer, I don't like the statement with no assignment on the LHS.
There isn't a functional difference.
The second construct just (subjectively) looks like it does what it does more than the first construct.
The counter argument is that the first construct is a common pattern, so is more easily recognised to do what it does.
They should do the same thing, but there is a better way.
Theoretically the second, assigning only if the value is falsy, could eliminate an assignment and be faster. Indeed in a jsperf we see it is (12%).
In fact the explicit if statement is just as fast as the condition-then-assign:
if(!options)
options = {};
Try the test on your browser/machine.
I think the explicit if is the most clear, and has no penalty.
Edit:
If you are expecting an object to be passed in to a function, then I think the better test is:
if(typeof options !== 'object')
options = {};
This will ensure that you have an object afterwards, even if it is empty. Any other test (for undefined, or falsiness) will permit a truthy non-object through like a non-zero number or a non-empty string. As the jsperf shows, however, this is ~15% slower. Since you only do this on entry to a function which will be processing objects, I would argue that is a worthwhile tradeoff, and is barely slower that the always-assign.
There is a functional difference: one uses var and the other does not. If there is any possibility that the options variable does not exist in the current scope, it is much better to use var rather than risk options leaking out into outer scopes implicitly.
If options is guaranteed to exist (for example, within a function whose parameters include options), the two statements are functionally identical so the problem reduces to the relative stylistic merits of options = options || {} versus options || (options = {}). Personally I see little difference: both require the same knowledge of how JavaScript's || operator works, so once you remove that factor from the equation, I would probably favour options = options || {} as being slightly more readable by virtue of being shorter and simpler. The developer's intention seems equally clear to me in either case.
There is indeed no functional difference between the two, even though their mechanics are not identical.
The first form sets the local variable options to be equal to the parameter options or to an empty object if the argument has a falsy value (e.g. if it has not been provided).
The second form evaluates to the value of the parameter options (if it's not falsy), otherwise it evaluates to the result of the assignment of the empty object to that parameter. So the difference from the first form is that if options is truthy, no assignment is performed.
Personally I consider the second form to be a less readable version of
if(!options) {
options = {};
}
to which is identical in both function and mechanics.
There is no functional difference, the idea is that options || (options = {}); is closer to what the programmer really want to express, which is actually:
if (typeof options == "undefined") {
options = {};
}
The || operator is used to make shorter code, not clearer code.
Definitely subjective, but I wouldn't use the second.
Reason: I feel that assignments in expressions anywhere deeper than the top-level = obfuscation.
Some C programmers like that (I used to, once), they do things like extra parens to make the assignment more clear... by making the whole expression look unfamiliar. Why bother if you can just be straightforward?
The most clear would probably be:
if (!options) options = {};

What is the best way to tell users of my library functions that passed variables are not of the correct type

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.

Categories

Resources