Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is var x = x = x || {} more thorough than var x = x || {}?

In my endeavour to write clean Javascript code as a beginner, I was recently reading this article about namespacing in JavaScript when I stumbled upon this paragraph:

The code at the very top of the next sample demonstrates the different ways in which you can check to see if a variable (object namespace) already exists before defining it. You'll commonly see developers using Option 1, however Options 3 and 5 may be considered more thorough and Option 4 is considered a good best-practice.

// This doesn't check for existence of 'myApplication' in // the global namespace. Bad practice as you can easily // clobber an existing variable/namespace with the same name var myApplication = {};  /* The following options *do* check for variable/namespace existence. If already defined, we use that instance, otherwise we assign a new object literal to myApplication.  Option 1: var myApplication = myApplication || {}; Option 2  if(!MyApplication) MyApplication = {}; Option 3: var myApplication = myApplication = myApplication || {} Option 4: myApplication || (myApplication = {}); Option 5: var myApplication = myApplication === undefined ? {} : myApplication;  */ 

Option 1 is certainly the one I have seen used most of the time, and I understand it well.

Option 2 is fine but seems to lack a var myApplication beforehand or a if(!window.myApplication) otherwise if myApplication is not in the global scope the condition if(!myApplication) would throw an error, wouldn't it?

Option 3 is the one I have trouble with: my understanding is that the myApplication = myApplication is executed first, with myApplication in the global scope (due to the var at the begining). My problem is that I can't think of a case where this option does anything more than option 1.

Option 4 in my eyes would have been better written window.myApplication || (myApplication = {}) to avoid throwing an error if myApplication is not in the global scope.

Option 5 is excluding the false-y values other than undefined but is it a good idea? If myApplication is say an empty string, the rest of the code is likely to fail, isn't it?

Would someone be able to shed some light on the differences between the different options and in particular explain why option 3 is described as more thorough?

like image 774
Jacques Gaudin Avatar asked Apr 16 '18 08:04

Jacques Gaudin


People also ask

What is var x {} in JavaScript?

var is the keyword that tells JavaScript you're declaring a variable. x is the name of that variable. = is the operator that tells JavaScript a value is coming up next. 100 is the value for the variable to store.

Does var has global scope?

The var statement declares a function-scoped or globally-scoped variable, optionally initializing it to a value.

What type of scope does var have?

Variables declared with the var keyword are always function-scoped, meaning they recognize functions as having a separate scope. This locally-scoped variable is therefore not accessible from the global scope.

How var works in JavaScript?

Basically, var declares a variable and you can also assign to it at the same time. Without var , it's assigning to the variable. Assigning will either assign to an existing variable or create a global variable of that name then assign to it.


1 Answers

If the article claims Option 3 is "more thorough," it's incorrect. There's no point to the middle of that assignment chain at all.

Would someone be able to shed some light on the differences between the different options and in particular explain why option 3 is described as more thorough?

First, a caveat: Here in 2018, you probably don't want to use any of these. Instead, use proper modules, either via one of the various module definition syntaxes (AMD, CommonJS, RequireJS) with a relevant tool, or via ES2015+ modules with import and export (and probably a relevant tool such as Babel and perhaps Webpack or Browserify, although current versions of Chrome, Safari, and Edge support modules natively, and Firefox does as well currently behind a flag).

Why is var x = x = x || {} more thorough than var x = x || {}?

It isn't.

Option 2 is fine but seems to lack a var myApplication beforehand or a if(!window.myApplication) otherwise if myApplication is not in the global scope the condition if(!myApplication) would throw an error, wouldn't it?

Yes. (Assuming that production occurs at global scope. if it's not at a global scope and there's an in-scope myApplication anywhere in the current scope chain, it won't throw because myApplication won't be an unresolved symbol.)

Option 3 is the one I have trouble with: my understanding is that the myApplication = myApplication is executed first, with myApplication in the global scope (due to the var at the begining). My problem is that I can't think of a case where this option does anything more than option 1.

No, if you have

var myApplication = myApplication = myApplication || {} 

this is the order in which things happen:

  1. var myApplication creates the global if it doesn't already exist, leaves it untouched if it does
  2. myApplication || {} is evaluated and takes either the value in myApplication (if it's truthy) or {} (if not); let's call that value1
  3. myApplication = value1 (the one in the middle) is performed, and the result is value1
  4. myApplication = value1 (the one on the left) is performed again for no good reason

Option 4 in my eyes would have been better written window.myApplication || (myApplication = {}) to avoid throwing an error if myApplication is not in the global scope.

Indeed.

Option 5 is excluding the false-y values other than undefined but is it a good idea? If myApplication is say an empty string, the rest of the code is likely to fail, isn't it?

Yes.

like image 174
T.J. Crowder Avatar answered Oct 14 '22 07:10

T.J. Crowder