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

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.

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.

Does ES6 const affect garbage collection?

In Kyle Simpson's new title, You don't know JS: ES6 and beyond, I find the following snippet:
WARNING Assigning an object or array as a constant means that value will not be able to be garbage collected until that constant’s lexical scope goes away, as the reference to the value can never be unset. That may be desirable, but be careful if it’s not your intent!
(Excerpt From: Simpson, Kyle. “You Don’t Know JS: ES6 & Beyond.” O'Reilly Media, Inc., 2015-06-02. iBooks.
This material may be protected by copyright.)
As far as I can see, he doesn't expand on this, and 10 minutes on Google turns up nothing. Is this true, and if so, what does "the reference to the value can never be unset" mean exactly? I have got into the habit of declaring variables that won't be changed as const, is this a bad habit in real concrete performance/memory terms?
WARNING Assigning an object or array as a constant means that value
will not be able to be garbage collected until that constant’s lexical
scope goes away, as the reference to the value can never be unset.
That may be desirable, but be careful if it’s not your intent!
That note sounds a bit more of a warning than is necessary (perhaps even a bit silly) and tries to make some sort of special case out of this situation.
With a const variable declaration, you can't assign to the variable something little like "" or null to clear its contents. That's really the only difference in regard to memory management. Automatic garbage collection is not affected at all by whether it is declared const or not.
So, if you would like to be able to change the contents of the variable in the future for any reason (including to manually remove a reference to something to allow something to be garbage collected sooner), then don't use const. This is the same as any other reason for using or not using const. If you want to be able to change what the variable contains at any time in the future (for any reason), then don't use const. This should be completely obvious to anyone who understand what const is for.
Calling out garbage collection as a special case for when not to use const just seems silly to me. If you want to be able to clear the contents of a variable, then that means you want to modify the variable so duh, don't use const. Yes, manually enabling garbage collection on a large data structure that might be caught in a lasting scope/closure is one reason that you might want to change the variable in the future. But, it's just one of millions of reasons. So, I repeat one more time. If you ever want to change the contents of the variable for any reason in the future, then don't declare it as const.
The garbage collector itself doesn't treat a const variable or the contents it points to any different than a var or let variable. When it goes out of scope and is no longer reachable, its contents will be eligible for garbage collection.
const has a number of advantages. It allows the developer to state some intent that the contents this variable points to are not to be changed by code and may allow the runtime to make some optimizations because it knows the contents of the variable cannot be changed. And, it prevents rogue or accidental code from ever changing the contents of that variable. These are all good things when used in an appropriate case. In general, you SHOULD use const as much as practical.
I should add the even some const data can still be reduced in size and make the majority of its contents available for garbage collection. For example, if you had a really large 100,000 element array of objects (that you perhaps received from some external http call) in a const array:
const bigData = [really large number of objects from some API call];
You can still massively reduce the size of that data by simply clearing the array which potentially makes the large number of objects that was in the array eligible for garbage collection if nothing else had a reference to them:
bigData.length = 0;
Remember, that const prevents assignment to that variable name, but does not prevent mutating the contents that the variable points to.
You could do the same thing with other built-in collection types such as map.clear() or set.clear() or even any custom object/class that has methods for reducing its memory usage.
That note in my book was referring to cases like this, where you'd like to be able to manually make a value GC'able earlier than the end of life of its parent scope:
var cool = (function(){
var someCoolNumbers = [2,4,6,8,....1E7]; // a big array
function printCoolNumber(idx) {
console.log( someCoolNumbers[idx] );
}
function allDone() {
someCoolNumbers = null;
}
return {
printCoolNumber: printCoolNumber,
allDone: allDone
};
})();
cool.printCoolNumber( 10 ); // 22
cool.allDone();
The purpose of the allDone() function in this silly example is to point out that there are times when you can decide you are done with a large data structure (array, object), even though the surrounding scope/behavior may live on (via closure) indefinitely in the app. To allow the GC to pick up that array and reclaim its memory, you unset the reference with someCoolNumbers = null.
If you had declared const someCoolNumbers = [...]; then you would be unable to do so, so that memory would remain used until the parent scope (via the closure that the methods on cool have) goes away when cool is unset or itself GCd.
Update
To make absolutely clear, because there's a lot of confusion/argument in some comment threads here, this is my point:
const absolutely, positively, undeniably has an effect on GC -- specifically, the ability of a value to be GCd manually at an earlier time. If the value is referenced via a const declaration, you cannot unset that reference, which means you cannot get the value GCd earlier. The value will only be able to be GCd when the scope is torn down.
If you'd like to be able to manually make a value eligible for GC earlier, while the parent scope is still surviving, you'll have to be able to unset your reference to that value, and you cannot do that if you used a const.
Some seem to have believed that my claim was const prevents any GC ever. That was never my claim. Only that it prevented earlier manual GC.
No, there are no performance implications. This note refers to the practise of helping the garbage collector (which is rarely enough needed) by "unsetting" the variable:
{
let x = makeHeavyObject();
window.onclick = function() {
// this *might* close over `x` even when it doesn't need it
};
x = null; // so we better clear it
}
This is obviously not possibly to do if you had declared x as a const.
The lifetime of the variable (when it goes out of scope) is not affected by this. But if the garbage collector screws up, a constant will always hold the value it was initialised with, and prevent that from being garbage-collected as well, while a normal variable might no more hold it.
The way garbage collectors (GC) work is when something is referenced by nothing ("cannot be reached"), the GC can safely say that something isn't used anymore and reclaim the memory used by that something.
Being able to replace the value of a variable allows one to remove a reference to the value. However, unlike var, const cannot be reassigned a value. Thus, one can't remove that constant from referencing the value.
A constant, like a variable, can be reclaimed when the constant goes "out of scope", like when a function exits, and nothing inside it forms a closure.

This is declaring a variable - right?

On a blog I see the following:
for (var key in map) {
if (map.hasOwnProperty(key)) {
var value = map[key];
// right, now we can get some work done
}
}
"Now you see that var key at the top of the for loop? That’s not
declaring a variable, oh no. It’s saying that somewhere else there’s a
variable called key"
Surely this is declaring a variable (if one named key did not previously exist in the scope chain)? What might the author mean by this?
Link: http://dannorth.net/2011/12/19/the-rise-and-rise-of-javascript/
Surely this is declaring a variable (if one named key did not previously exist in the scope chain)?
Yes, it is, within the function that for loop is in. (The variable is not limited to the for loop like it would be in, say, Java. Its scope is the entire function it's in.)
More about var (on my blog): Poor, misunderstood var
What might the author mean by this?
It sounds sarcastic, actually, like the author is trying to make a point by saying the opposite of what they mean.
Edit Since you've posted the link, here's the complete quote:
Now you see that var key at the top of the for loop? That’s not declaring a variable, oh no. It’s saying that somewhere else there’s a variable called key (right at the top of the nearest containing function, it turns out). Oh, and that key variable is visible all through that function, and any functions it contains, not just tucked away in the for loop. Brilliant!
The point he's trying to make there is that the variable isn't just limited to the for loop. But that initial statement is flatly incorrect. I know what he means, but it's not what he said.
Re the first point above, in ES6 JavaScript will be getting a new keyword, let, which would declare something only for the for loop:
// New in ES6, you probably can't use this yet
for (let key in map) {
// ^^^---------------- change is here
if (map.hasOwnProperty(key)) {
let value = map[key];
// ^^^----------------- probably want to change this one, too
// right, now we can get some work done
}
}
Some engines already support it, but you can't use it broadly yet, as many don't. And in theory the ES6 draft spec could change, though I really doubt it will. :-)
That, actually is a full definition of a variable from an iterator value that's fetched at the current iteration of variable map. It's a declaration + initialization.
To understand the notion of iterators you would have to go deeper and look into the underlying interpreter code which supports the value of the key to every iteration of the loop.
Also this: "Now you see that var key at the top of the for loop? That’s not declaring a variable, oh no. It’s saying that somewhere else there’s a variable called key" sounds stupid, doesn't explain anything and creates confusion.
I wouldn't read such articles, because such a statement shows that the author isn't really acquainted with the real world behind JavaScript - that is C/C++ or even assembly, which work at the basic memory level, and use constructs called iterators to support values to loops in case of data structures that are more advanced than simple arrays.

Cannot Set Property ... of undefined --- bizarre

I'm getting a bizarre error in Chrome... check out the screenshot below.
I define record using object literal syntax.
I try setting the "id" property and get the exception.
I've tried both :
record['id'] = 'wtf';
and also
record.id = 'wtf';
I use this type of syntax all over the place in my script.... what could be going on here ?
Is this a bug in Chrome ?
EDIT :
I've solved the problem for now, but I'm still not sure why this is happening.
I moved the definition of record to occur outside of the if block. Anyone know what could be occurring ? I thought all variable declarations were scoped to the function and therefore this shouldn't be an issue.
The problem is most likely that dl is less than or equal to zero, so the statement that initializes record doesn't get executed. From your indentation, it looks like you intended for both statements to be part of the if block, but with no braces, the record['id'] = 'wtf'; statement gets executed no matter what.
By moving the variable initialization outside the if statement, you forced it to happen in any case and moved the assignment inside the if block (which, I'm assuming is what you wanted).
Probably a better way to solve it is adding braces like this:
if (dl > 0) {
var record = {};
record.id = 'wtf';
}
Unless you really do want to initialize record in both cases.
You are correct about variable declarations being scoped to the function, but the assignment doesn't happen until you get to that point in the code. record was in scope, but it still had its default value of undefined because you hadn't assigned anything to it yet.
Works for me, no reason it shouldn't work. Are you sure it's referring to that exact line? what if you alert(record) before you set it? Have you tried to debug it yet?

Javascript global variables or object variables

I prefer to declare one Javascript file for my all website. I am trying to decrease the usage of global variables. My examples at the below, in both case each object has a myName field.
I would like to know when they are initialized?
And In terms of memory and efficiency which one is more effective?
For variable a, is declaring a.myName the same as global "var myName = Rebecca" ?
var a = {
myName : 'Rebecca' ,
sayHello : function() {
console.log(this.myName);
}
};
var b = {
myName : function() {
return 'Rebecca';
},
sayHello : function() {
console.log(this.myName());
}
};
Thanks
I believe these will be initialized identically (i.e. when the code is reached). What's different is what's happening when they are initialized and where the load is placed when their data is actually required.
To me, it would depend a lot on what you were expecting to have in myName. If it were just a string, I'd avoid the function and go with choice a. On the other hand, if there were a great deal of logic involved and that logic might not need to be invoked (for example, if it only gets executed when a user clicks on a button or the application reaches a certain state), I'd go with choice b. As I understand it, the function does consume memory and won't get garbage collected (which is a minus), but it also won't consume CPU resources until it's actually needed (which can be a huge plus).
I'm not sure I understand the question, but I'd say it's not the same. If the only member of a is myName then the two are equivalent (both are occupying the global namespace. But if you have multiple properties, the savings become obvious. From your examples, I think it's clear you understand this, so again I may not understand the question.
They will be initialized when the statements are first encountered. In a, 'Rebecca' is initialized as the value for the myName key. In b, it's just data internal to the myName (anonymous) function. a will be slightly more efficient because it avoids a function call. I also find it more readable in this simple example.
I find the choice to put everything in a single file questionable. In some cases, you want a modular design. And since you're worried about efficiency (albeit perhaps prematurely), note that having one big file can actually hurt performance if pages include code they don't need.
1) They are initialized when the script is processed in the browser, unless you declare the objects in an event handler. In that case the object is created when the event script is executed.
2) In terms of efficiency, a will probably be more efficient. Note though that in the first case you use a.myName and in the second b.myName() to get the value of the property.
3) No. If you assign a value to a property of an object, you always have to get that value through the object. In this case either a.myName or a['myName'].
a doesn't make any sense, because you're logging a function reference. B is the way to go, since you're actually invoking the method, using ().

Categories

Resources