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

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.

Related

SonarQube displaying to 'remove this useless assignment to local variable'

Why is SonarQube giving this error? How should I fix it? Their rule page does not specify the solution,
Remove this useless assignment to local variable "validateAddressRequest".
validateAddress() {
if (this.propertySitusMailingForm.valid) {
let validateAddressRequest: ValidateAddressRequest = new ValidateAddressRequest();
let propertySitusData = new PropertySitusAddress(this.propertySitusMailingForm.value);
validateAddressRequest = convertToValidateRequest(propertySitusData);
this.validationService.validateCall(validateAddressRequest);
}
}
This site says that the error occurs when:
A value is assigned to a variable or property, but either that location is never read later on, or its value is always overwritten before being read. This means that the original assignment has no effect, and could indicate a logic error or incomplete code.
On the first line of the if block, you assign to validateAddressRequest, but then on the third line of the if block, you overwrite validateAddressRequest without having read the previously assigned variable. So the first line is useless.
Declare validateAddressRequest only when calling convertToValidateRequest instead.
const validateAddressRequest = convertToValidateRequest(propertySitusData);
Note that you almost certainly don't need the type annotation - if Typescript knows that convertToValidateRequest returns a ValidateAddressRequest already, there's no need to do so again with the new variable. You can do so if you think it's unclear otherwise, or if you don't have type Intellisense, but it may just be noise.
If you were declaring the variable with let so as to enable assignment to it in the future, keep in mind that it's best to avoid reassignment whenever possible, and it's almost always possible to avoid reassignment. If you need another variable that contains a ValidateAddressRequest, give it a different variable name so that you can use const to declare both variables; that makes the code more understandable at a glance, when a reader can be sure that a particular variable reference isn't ever going to be reassigned.

Why is it console.log will sometimes print undefined for a variable which has been exported?

So I'm working in node.js (beginner) and I'm trying to use variables which are in a different script. What I've found is that sometimes the variable comes back as undefined. For instance:
//Doesnt like this
var peaches = 'Peaches';
exports.peaches;
// Likes
exports.peaches = 'Peaches'
Now, It I require this script, I find that if I use the top method, the printout is 'undefined', whereas using the second method, the printout is 'Peaches'.
This wouldn't affect me too much (since I could just always use the second method), however, when I try to export an array using the second method it prints out as undefined. But the confusing thing is that this only happens when I try to import two arrays (the second will always give 'undefined' yet the other will work. Is this to do with the flow of execution of the program? (So it has time to execute the first script, but not the second?
Try this:
var peaches = 'Peaches';
exports.peaches = peaches;
In your first "method" you are not actually exporting anything.
The exports variable is just a plain JavaScript object created for each
of your modules.
Generally, if you want to return any javascript module or Object.
You use the module.exports object, module.exports is the actual object that is returned when you require that exported module.
The exports object which you are using to export, it's a shorthand "alias" for module.exports.
Now, since you have not assigned any object to your exports object, it is coming as undefined.
Think of it as this way.
object = {
key1:'value1',
key2:'value2'
}
console.log(object[key1]) // value1
console.log(object[key2]) // value2
//Now, if you try to access something that is not assigned
console.log(object[key3]) // undefined
Same is happening with your exports object,
You have not assigned anything to exports.peaches, when you do.
exports.peaches //hence undefined while import
Instead, do
exports.peaches = 'peaches'
I hope that make sense!.

Are there intrinsically read-only objects in Javascript?

I have an odd situation in my Javascript code which I cannot explain. So far it has been observed only on Safari/Mac.
I have a line like this:
dict[id].sliceHovered = true;
And sometimes it throws an error:
Attempted to assign to readonly property.
Also:
dict is a bare blank object which I create myself with dict={}.
id is supplied by outside data, so it can be anything (I don't yet know which particular value causes this).
sliceHovered is obviously not a name of something that Javascript has built
in.
The objects in the dict are of my own type. They have a sliceHovered member, but it's not a Javascript defined property (as in Object.defineProperty()), just a regular property (the constructor executes this.sliceHovered=false).
"use strict" is on.
Object.freeze(), Object.seal(), Object.preventExtensions() and const are not used anywhere in the entire codebase.
Thus it's extremely puzzling as to how such an error could be thrown here. If I had an indexing error and dict[id] would be undefined or null, the error would be different. My only idea is that since the dict is created as dict={} then it inherits from Object and maybe id maps to some inherited property. But that means that the object returned from dict[id] would have to be read-only itself, because sliceHovered is definitely not a name of an existing Javascript property.
However I cannot think of any Javascript objects that would be intrinsically read-only like that.
Any ideas what could be wrong here?
You can check this situation
My only idea is that since the dict is created as dict={} then it inherits from Object
with: var dict = Object.create(null);
Also try to use Object.getOwnPropertyDescriptor(dict, id) to make sure descriptors have right values.

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.

Accessing Object's Data Via Another Variable Name

It's super late and my mind is blanking right now, but let's say I have variable filename and it's storing the name of another variable marker. The variable marker is an array and contains the object & property position: new google.maps.LatLng(42.2550,-114.3221).
I've been stupidly trying to access it via filename.position which of course returns undefined, since it's searching the literal filename for a 'position' property that does not exist.
But how could I pull marker.position by using filename? Is there some nifty jQuery trick for, uh, 'resolving' a variable to its contents? I'm brain fried. I know I've done this before.
If it's possible in your script, you can store the data not just in variable, but in a property of some object (usually it's more convenient to use global one).
For example
var myObj = {};
myObj.marker = new google.maps.LatLng(42.2550,-114.3221); // or anything else
Then you will be able to get this property using a variable like this:
myObj[filename].position
In this case i would also recomment to check for myObj[filename] existance using typeof structure, just to make sure such property exists in myObj.
if (typeof myObj[filename] !== "undefined") {
// do something
}
As apsillers noted, you could use global window object for this as well. But if your marker variable was defined inside some other function (i.e. not global), you won't be able to access it with window.marker or window[filename] as it will be out of scope.
Second way is to use eval() function which i'd strongly recommend to avoid.
Try this :
window[filename].position;

Categories

Resources