Using emptiness as syntactic sugar to protect against implicit globals, yes or no?

I was thinking about the javascript programming style, and I was wondering if it makes sense to add some syntactic sugar to protect against the easily made mistake of using an implicit global, i.e.:

var OuterFunction = function() { // closure container var renamedCounter = 0; // someone renamed counter, this.resetCounter = function () { counter = 0; // ... but forgot to check the inner functions as well. return this; }; return this; } 

In this example, the counter suddenly becomes a global variable, and the other is locally bound to OuterFunction instances.

By "declaring" a void variable fixed with the closure, you get a free statement, much like any other code that uses counter without its purpose.

 this.resetCounter = function () { void counter; // this will throw an Error if counter is not in scope. counter = 0; return this; }; 

Edit : as jleedev pointed out , just using the variable name itself seems to check if it exists, i.e.

 this.resetCounter = function () { counter; counter = 0; return this; }; 

will work just as well.

I see the following benefits:

  • This is a short description.
  • This appears to be a variable declaration in which it resides.
  • Edited to add . If done sequentially, it is very simple to check the syntax (meat or program) to detect errors of this kind.

On the other hand:

  • This is confusing. The code actually does nothing.
  • Future translators may consider this as meaningless, painless code and optimize it.

Are there any aspects that I'm missing? Is this a stupid idea, or is it at least somewhat justified?

Question asker Edit : This should be a community wiki question, but I don’t see a checkbox to change it to this. I vaguely remember that there is one.

Edited for great stupidity : of course, += tries to get the value of the expression before the increment. Therefore, we renamed the example to resetCounter , not incrementCounter , so that it makes little sense.

+4
source share
2 answers

According to the specification of ECMASCript Language :

11.4.2 void statement

Production of UnaryExpression: void UnaryExpression is rated as follows:

  • Let expr be the result of evaluating UnaryExpression.
  • Call GetValue (expr).
  • Return undefined.

NOTE. GetValue must be called even if its value is not used, as it may have observable side effects.

Therefore, it should never be optimized.

However, this does not IMHO remotely look like a variable "declaration", and, of course, does not act as one, so this should be avoided.

EDIT: indeed, it cannot be used exactly because calling GetValue can have side effects, for example, if this variable is actually a property with a β€œgetter” on it.

+3
source

Not sure if this is the answer to your question, but ECMAScript 5 introduces strict mode that prevents implicit global declarations:

Assigning an undeclared identifier or otherwise an unsolvable reference does not create a property in the global object. When simple assignment occurs in strict mode code, its LeftHandSide should not evaluate an unsolvable reference. If it throws a ReferenceError exception ( 8.7.2 ). LeftHandSide may also not refer to a data property with the attribute value {[[[Writable]]: false }, to an accessor property with the attribute value {[[Set]]: undefined }, or to a nonexistent property of an object whose internal property is [[Extensible] ] is false . In these cases, a TypeError exception is thrown ( 11.13.1 ).

In browsers that support it (which Firefox 4 now seems to be), you can activate strict mode with

 "use strict"; 

During development, I use JSLint to check my files for errors or problematic code. This does not mean that you mean global variables.

+1
source

Source: https://habr.com/ru/post/1343459/


All Articles