0

The following pattern is found throughout a Javascript codebase. A variable is defined and initialized either with its value if it already exists or with an empty object. It is then immediately overwritten.

var outerVariable = outerVariable || {};
outerVariable = {
    // inner variable definitions follow
    // ...
};

Does this pattern serve any useful purpose?

R.J. Dunnill
  • 2,049
  • 3
  • 10
  • 21

3 Answers3

3

No, I don't believe this is doing anything useful - you might as well just write:

var outerVariable = {
    // inner variable definitions follow
    // ...
};

... and drop the first line...

It doesn't matter if the outerVariable is already defined, since we can overwrite it (Declaring a Javascript variable twice in same scope - Is it an issue?).

Using 'let' and 'const' is another matter.. you cannot redefine these variables.

jsdeveloper
  • 3,945
  • 1
  • 15
  • 14
-1

Yes. Defines an empty object, if not exists. Then he does something on this object.

Slawomir Dziuba
  • 1,265
  • 1
  • 6
  • 13
  • 1
    But he immediately overwrites it. What's the point of preserving its initial value? – R.J. Dunnill Mar 12 '19 at 23:09
  • It does not necessarily replace. Why did I get a minus for it? – Slawomir Dziuba Mar 12 '19 at 23:11
  • *"It does not necessarily replace."* `outerVariable = {...}` certainly assigns a new value to `outerVariable`. – Felix Kling Mar 12 '19 at 23:12
  • OK, I did not express myself correctly. Sorry, my English is not the best. The first line is correct. Protects outerVariable from overwriting if it exists. The second line overwrites it, but can be changed eg. outerVariable.prototype.foo = 'Blach'; etc. – Slawomir Dziuba Mar 12 '19 at 23:30
-1

This particular pattern when seen at the top of files is used to create a namespace, i.e. a named object under which functions and variables can be created without unduly polluting the global object.

1 Preventing override:

Imagine you have your code split over multiple files and your co-workers are also working on an Object called Base. Then it could lead to the case that someone already defined Base and assigned functionality to it (like a pizza function). Then you would override it, if you were not checking if it already exists.

// Definition of co-worker "A" in "A.js"
var Base = {};

Base.pizza = function() {
  alert('I like pizza!');
};

// Definition of co-worker "B" in "B.js"
var Base = {};

Base.donut = function() {
  alert('I like donuts!');
};

In this case the pizza function will be gone if you load the JavaScript file B.js after A.js in your HTML because B defines a new Base object (and thus overrides the existing one from A) so it only knows about the donut function.

So you need to use var Base = Base || {}; which means "Base will be assigned to Base (if it exists already) or a new blank object (if Base does not exist already).

Solution

    var Base = Base || {};
    
    // Definition of co-worker A in A.js
    Base.pizza = function() {
      alert('I like pizza!');
    };
    // Definition of co-worker B in B.js
    var Base = Base || {};
    
    Base.donut = function() {
      alert('I like donuts!');
    };

Because A and B are now checking for the existence of Base before they define their methods, you can load A.js and B.js in any order without overriding each other's methods (if they have different names). So you will always get a Base object which has the methods pizza and donut (Cheers!).

2 Defining a new object

If you've read through the first example then you already now what's the purpose of the || {}.

Because if there is no existing Base object then the OR-case will become active and creates a new object, so you can assign functions to it. Like:

var Base = {};

Base.pizza = function() {
  alert('I like pizza!');
};

Hope it Helps!

Community
  • 1
  • 1
Abdullah Aziz
  • 700
  • 5
  • 11
  • 1
    They're not appending to Base, however. They're overwriting it. – R.J. Dunnill Mar 12 '19 at 23:37
  • 1
    are you working in the global namespace with multiple files. this pattern is mostly use in namespace. please check this namespace patterns: https://www.oreilly.com/library/view/learning-javascript-design/9781449334840/ch13s15.html. Please refer to the object literal notation. Hope it will help. – Abdullah Aziz Mar 13 '19 at 00:10
  • you can also see here http://2ality.com/2011/04/modules-and-namespaces-in-javascript.html. section 1.6 Managing namespace. Make sure you are using same namespace. because if it is overwriting that mean the variable does not exists in the namespace. it is simple circuit-breaker statement which you already mentioned in your question that you know what it means that if the variable exists use same variable otherwise initialize with empty object. – Abdullah Aziz Mar 13 '19 at 00:19
  • 2
    This is a great explanation for (one possible use of) the first line of code in the question. Note the *second* line of code, though, which replaces the original object with a new one... – Daniel Beck Mar 13 '19 at 12:47