Javascript module pattern with undefined specified - javascript

I believe jQuery uses undefined in the module pattern to avoid it being redefined to an unexpected value. I thought about doing this but whenever I compare undefined I tend (always?) to use
typeof foo === 'undefined'
So is there any point doing this:
(function (win, doc, RG, undefined)
{
// App goes here
})(window, document, typeof RGraph === 'object' ? RGraph : {});

whenever I compare undefined I tend (always?) to use typeof foo === 'undefined'
Well if you don't use undefined in your module then there is no point in declaring it as a parameter to ensure its value.
However, there's a question mark after your "always", and you can hardly know who else might work with your code in the future, so it still might be advisable.

There are three ways to test whether a value is undefined:
Method 1: Use typeof:
if (typeof value === "undefined") {
// do something
}
Method 2: Compare it with the variable undefined:
if (value === undefined) {
// do something
}
Method 3: Compare it with void 0:
if (value === void 0) {
// do something
}
Q: Which one should you use?
A: There are many factors to consider:
In terms of understandability typeof and undefined are the best.
In terms of minimum characters undefined is the best when minified.
In terms of performance (http://jsperf.com/type-of-undefined-vs-undefined):
Both undefined and void are at par in most browsers (notably Firefox and Chrome).
In Chrome typeof is slower than the other two but in Firefox it is the fastest.
Using typeof is the only way to test whether or not a variable exists.
Based on these factors I would say that undefined (method 2) is the best method. There's always the problem of undefined being overwritten. However if you're using the module pattern (which you should be doing in the browser) then you can get undefined for free:
(function ($, undefined) {
// you can use `undefined` safely here
}(jQuery));
Hence if you're using the module pattern then I would suggest you use the second method. It is readable, understandable and concise. The only disadvantage is that you won't be able to test whether or not a variable exists. However you can always fall back to typeof for that.

Related

What is the better way to check if a variable is undefined? [duplicate]

I've seem different approaches for (strict equality) checking for undefined:
if (something === undefined)
if (typeof something === 'undefined')
if (something === void 0)
and probably others
In a happy scenario their behavior is the same. In other words, they all work.
But, considering all the quirk corners of JavaScript, are they truly identical in behavior?
If yes, why people choose other approaches rather than the first? Is it some sort of legacy or misconception? Because the first one it's obviously the most clear in both readability and intention demonstration.
if (something === undefined) is the standard normal way
typeof something === 'undefined' on a declared variable is mostly an overdefensive solution dating from the time where you could change window.undefined. If you don't know if your variable is declared, it has the advantage of not raising an error but I don't think a legit code should support the case of a variable whose declarative state is unknown.
void 0 (or void anything) is a normalized way to get undefined so it's equivalent to the first one but useless.
Literally undefined
Test for existence, as in "variable not declared".
Same as undefined. Older version of the JS standard let you change the value of undefined as it's just a variable. void 0 is undefined, it's safer.
An extra one:
if (x == null). Tests for undefined and null because undefined == null but remember, undefined !== null
In JavaScript there's a type 'undefined' and a value undefined. The value undefined is of type 'undefined'.

get property safely from an object in a node application

First a little bit of context (you can skip this part if you prefer to focus on code).
I joined a new project that will be integrated in a nodeJS's platform. Our team does have experience with JEE enterprise Web Apps. That sets up our background. This new project will consume REST APIs, aggregate some data, implement some business logic and pass these data to front-end consumer. Sort of lightweight microservice architecture.
Some co-workers started to work on the project and I found it that in the source code we do have a lot of code snippet like if (foo != null && foo.property != null) {return foo.property.value;}
Foo being supposed to be an object passed as an argument to a function which would implement that kind of test.
A snippet example will talk more.
Let's pretend that's the response of an API i am consuming. I want to write a small function which would return statusValue if the object does exist, if it's not null or undefined, not empty and the property does exist and isn't blank or empty for instance.
var response = {
"services":[],
"metadata": {
"status": "statusValue"
}
};
That's how it is as for now :
function getStatusValue(response) {
if (response != null && response.metadata != null) {
return response.metadata.status;
}
};
What would be considered as a best JS practise to implement that (we are also using lodash so maybe it's a better option to use lodash internals for that). I am just fearing we are transposing our Java habbits.
Basically i would like to know how to check for null, undefined, empty, blank safely (if that makes sense). What would be the JS best practice for that in 2016 with libraries such as lodash and stuff.
When checking for properties of an object, checking for loose equality to null is not enough.
Loose equality (==) employs type hinting in JavaScript, which attempts converting the members to a common type that can then be used for determining whether they are equal or not.
As such, best practices for JavaScript dictate that strict equality (===) is always to be used, in order to avoid edge-case scenarios or unknown behavior when checking for values or types.
You can find more info about loose vs strict equality here:
https://developer.mozilla.org/en/docs/Web/JavaScript/Equality_comparisons_and_sameness
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators
While this is not a must-have in your function, it is a good practice to follow and develop as a habit, so that on later code the implications of loose equality (==) could be avoided (e.g. avoiding '3' == 3, when a number or string type is expected).
Although considered a downside of the language by some, using null is similar in intent as checking for undefined, but is actually meant to express in the code that the coder is expecting an object (or lack of) to be provided, instead of a primitive type (number, string, boolean, function). This differs from Java, or any other typed language, where null is used for Object type defined variables; but in JavaScript there's no constraining a variable to given type.
You can find out more details about null at MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/null
In practice, and especially when dealing with values that come outside of a unit - which is the case of any API - is considered a best practice to actually check for the type being an object, in order to make sure it has properties.
While your code is not incorrect, it does show that there's not much attention to best practices, which eventually will lead to writing buggy code.
My suggestion for your code, following best practices and independent of any library, is:
function getStatusValue(response) {
// must be of type `object`, to have properties.
if (typeof response === 'object' &&
// any variable of type `object` might be `null`, so exclude that.
response !== null &&
// `metadata` property must be of type `object`, to have properties.
typeof response.metadata !== 'object' &&
// `metadata` is of type `object`, check for not being `null`.
response.metadata !== null) {
// `status` property is expected to be a string, given by the API spec
if (typeof response.metadata.status === 'string' &&
// on strings, we can access the `length` property to check if empty string (0 chars).
response.metadata.status.length > 0) {
// all good, return `status` property.
return response.metadata.status;
} else {
// `status` property is either not a string, or an empty string ('').
}
} else {
// invalid `response` object.
}
}
Also, it might be easier to create or use from any libraries you integrate, a function to check for a valid object; something like _.isObject or this:
function isObject(o) {
return (typeof o === 'object' && o !== null);
}
which you could later be used in the above snipped like so:
function getStatusValue(response) {
if (isObject(response) && isObject(response.metadata)) {
if (typeof response.metadata.status === 'string' &&
response.metadata.status.length > 0) {
return response.metadata.status;
} else {
// `status` property is either not a string, or an empty string ('').
}
} else {
// invalid `response` object.
}
}
As a final thought, as it is clearly visible, following best practices does increase the size of your code, but the benefit is that the resulting code is much safer, with less chances of throwing exceptions (root of many app crashes), easier to collaborate on, and easier to build tests/coverage for.
Using Lodash, you can use the _.isNil(response) function documented here.
In general, I would check a variable like this:
if (typeof x !== 'undefined' && x !== null) {
// x has some value
}
You should not check whether x === undefined because if x is undefined, you'll get a dereference error.
I would implement this using the following function:
var response = {
"services":[],
"metadata": {
"status": "statusValue"
}
};
function getStatusValue(res) {
if (res && res.metadata)
return res.metadata.status || 'not found';
else
return 'not found';
}
console.log(getStatusValue(response));
The if statement will return false if res or res.metadata are undefined and if they both exist, it will return res.metadata.status only if it's defined or 0, otherwise it'll return 'not found'.
Here is a (more concise) way to do such a thing with just JS:
var obj = ...;
var val = obj && obj.prop && obj.prop.val;
val will be undefined/null if either obj or obj.prop are; otherwise it will be obj.prop.val.
This works because of the short-circuit evaluation of &&. It's literal behavior is this: if the first operand is falsey, it evaluates to the first operand. Otherwise, it evaluates to the second. This works as expected for booleans, but as you can see, it can be useful with objects.
|| has similar behavior. For example, you can use it to get a value, or a default if the value is falsey (e.g. null):
var val2 = val || "not found";
Note that this would evaluate to "not found" if val is anything falsey, including 0 or "".

Javascript typeof of undefined objects subproperty

Let's say I would like to check if a property to the object Foo is defined or not, I would use in this scenario:
typeof Foo.property != 'undefined'
But if not only the property does not exists, but also the object is undefined, this results in an error.
Is there any single line way to check if an objects property is defined, and return false in the following cases:
if the object property is not defined
if the object is not defined
WHY I WANT THIS: I am writing a script in NodeJS, which uses a class, which would be used in the front end also, and instead of maintaining two different files, which would end up being basically the same except for minor changes for the two environments, I would like to differentiate between the environments with some basic IF logic.
OTHER POSSIBLE USE CASES: Let's say we have the following object:
function Foo() {
this.case1={
info1: 'something',
info2: 'something',
.....
info1000: 'something'
}
this.case2={
info1: 'something',
info2: 'something',
......
info1000: 'something'
}
}
If I would like to decide which case applies to me, and the decision lies in one of the inner info's, I would first have to check if the respective case exists, and then if the respective info exists(2 conditions):
if (typeof Foo.case1 != 'undefined') && (typeof Foo.case1.info1 != 'undefined')
If this is a much deeper nested object, there would be a lot of condition checking and typing, to get some basic information: if case1 does not exist at all, then I will use case2.
You could use an and (&&) clause.
typeof Foo !== 'undefined' && typeof Foo.property !== 'undefined'
Or put more simply:
Foo !== undefined && Foo.property !== undefined
Edit: As David Titarenco pointed out, this works due to something known as short-circuit evaluation. That basically means that if the first part evaluates to false (Foo !== undefined) then the second part is never evaluated.
The simplest answer that comes to mind is this. It is not as 100%-strict as yours, but it would take a very unusual situation to break it:
if (Foo && 'property' in Foo) {
The Foo object is evaluated as boolean. A null or undefined type will be false, any object will be true. We also check the "key" side of the key/value pair, rather than the value. It is technically possible to have the key property, but for it to have the actual value undefined. This will return false in that case.
The one caveat: If Foo is another value type: true, 12, function()..., then the first condition may pass (but I don't believe the second one will)
Okay, I came up with a small function, which on initial testing does what I wanted, but I've only tested it for like 5 minutes, so there could be errors in it, if yes, please point it out:
function isDefined(path, namespace) {
if (typeof namespace == 'undefined') {
namespace=global;
// global is the default namespace for NodeJS,
// change this to window if you use it in a browser
}
path=path.split(".");
for (var i=0;i<path.length ;i++)
{
if (typeof namespace[path[i]] == 'undefined') return false;
else namespace=namespace[path[i]];
}
return true;
}
Usage: if you would want to test for example if Test.Test1.Test2.Test3.Test4.Test5.Test6 is defined you can use it like this:
if (isDefined('Test.Test1.Test2.Test3.Test4.Test5.Test6')===true) {
//it is defined
}

Best practice of checking if variable is undefined

I was having some issues in my conditions concerning undefined variables. What is, to sum it up, the best way to check if a variable is undefined?
I was mainly struggling with
x === undefined
and
typeof x === 'undefined'
You can use both ways to check if the value is undefined. However, there are little nuances you need to be aware of.
The first approach uses strict comparison === operator to compare against undefined type:
var x;
// ...
x === undefined; // true
This will work as expected only if the variable is declared but not defined, i.e. has undefined value, meaning that you have var x somewhere in your code, but the it has never been assigned a value. So it's undefined by definition.
But if variable is not declared with var keyword above code will throw reference error:
x === undefined // ReferenceError: x is not defined
In situations like these, typeof comparison is more reliable:
typeof x == 'undefined' // true
which will work properly in both cases: if variable has never been assigned a value, and if its value is actually undefined.
I guess both, depending on what you're testing? If it's a property, I'd always use x === undefined, since it's clearer (and it seems faster).
As others said, x === undefined won't work if x is not declared. Personally, I find that an even better reason to use it, since normally I shouldn't be checking if a variable is declared at all — it would usually be a sign of a coding mistake.
I've seen a lot of the other version for testing arguments — f = function(x) {if (typeof x == 'undefined') …} — if I'm code-reviewing code like this I'll tell them to change it. We know for a fact the variable is declared, and making an habit of writing it that way increases the chance you'll waste time chasing typo bugs.
The main exception is when you're trying to check if a component or library was loaded or initialized correctly. if (typeof jQuery == 'undefined') … makes sense. But in the medium term, all this should become modules anyway, in which case the typeof test should in my opinion be phased out as harmful.
(Also, personally, I prefer if (window.jQuery === undefined) for that case too. It's not portable for isomorphic code, though.)
x === undefined
does not work if variable is not declared. This returns true only if variable is declared but not defined.
Better to use
typeof x === 'undefined'
You could use any of them.
If you would like to check if a variable is undefined or null you could use:
x == null
This results in true if x is undefined or null.

Are these undefined checking identical in behavior?

I've seem different approaches for (strict equality) checking for undefined:
if (something === undefined)
if (typeof something === 'undefined')
if (something === void 0)
and probably others
In a happy scenario their behavior is the same. In other words, they all work.
But, considering all the quirk corners of JavaScript, are they truly identical in behavior?
If yes, why people choose other approaches rather than the first? Is it some sort of legacy or misconception? Because the first one it's obviously the most clear in both readability and intention demonstration.
if (something === undefined) is the standard normal way
typeof something === 'undefined' on a declared variable is mostly an overdefensive solution dating from the time where you could change window.undefined. If you don't know if your variable is declared, it has the advantage of not raising an error but I don't think a legit code should support the case of a variable whose declarative state is unknown.
void 0 (or void anything) is a normalized way to get undefined so it's equivalent to the first one but useless.
Literally undefined
Test for existence, as in "variable not declared".
Same as undefined. Older version of the JS standard let you change the value of undefined as it's just a variable. void 0 is undefined, it's safer.
An extra one:
if (x == null). Tests for undefined and null because undefined == null but remember, undefined !== null
In JavaScript there's a type 'undefined' and a value undefined. The value undefined is of type 'undefined'.

Categories

Resources