0

Been reading Javascript Design Patterns from Addy Osmani, and in the document this simple assignment is used to 'prevent overwriting an already existing object/ namespace':

var myNS = myNS || function() {};

So I understand it assigns the same object to the variable if it already exists, or creates an empty one if it (ideally) doesn't. So suppose I add a method to this object's prototype, but an already-existing, similarly-named object already had a similarly-named method that outputted 'Hi!'. The following should happen, right?

myNS.prototype.sayHello = function() { return 'Hello!' }; 
myNS.sayHello(); // Hello! ??

And the original myNS.sayHello() // Hi! is still overwritten, no? So i.e. what does conditional variable assignment in this case do, except add one level of name-collision avoiding ? Or am I completely wrong on this?

webketje
  • 10,376
  • 3
  • 25
  • 54
  • Your object is not a function; adding things to its prototype property makes no sense. (It doesn't even *have* a prototype property, most probably.) – Pointy Jun 19 '14 at 18:56
  • The logical `||` does nothing to help in that case. If you need to prevent overwrite of an existing `.prototype.sayHello` method, then you'd need a similar guard. The point is to understand the approach, and use it wherever it's needed. – cookie monster Jun 19 '14 at 19:04
  • @cookiemonster, Slightly confused by what you mean with *similar guard*. Could you briefly explain (or show a line of code)? – webketje Jun 19 '14 at 19:06
  • 1
    `myNS.prototype.sayHello = myNS.prototype.sayHello || function() { return 'Hello!' };` ...assuming the goal was to not overwrite the existing property. – cookie monster Jun 19 '14 at 19:06
  • Ah k thanks, clear now – webketje Jun 19 '14 at 19:07

2 Answers2

1

The idea is that you might have a script which adds a sayHello function to myNS and a different script that adds a sayGoodbye function to myNS.

Using the var myNS = myNS || {}; pattern in each of those scripts means that you can:

  • load one of the scripts without trying to write to an object that doesn't exist
  • load both of the scripts, in either order, without the second one destroying the first one

It doesn't provide protection against two scripts overwriting the same method of the object.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • So it's only got to do with a modular JS approach and nothing with avoiding name-collision? – webketje Jun 19 '14 at 19:03
  • 1
    The name collision protection to stop the `myNS` from the `sayHello` script from colliding with the `myNS` from the `sayGoodbye` script. – Quentin Jun 19 '14 at 19:11
1

The purpose of that form of assignment is not to avoid a naming conflict, it's to keep an already existing object.

For example, if you have two pieces of code that adds properties or methods to an object, and you don't know which one of them runs first, or can't control that, you can let both use an assignment like that:

var myNS = myNS || {};
myNS.doSomething = function(){ ... };

and somewhere else:

var myNS = myNS || {};
myNS.doSomethingElse = function() { ... };

When both codes have run, you have an object with both methods, and neither code relies on the other to exist or execute in a specific order.


If you want a new object, you should simply create a new object.

If you only want to avoid the naming conflict, then you should keep your code in a function scope so that all your variables are local to that scope, and will shadow any variables with the same name from the global scope. This approach is used by many libraries to put as little as possible in the global scope that could interfer with other libraries.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • one additional question: doesn't that mean that whatever you create always has a single point of failure? (ie, if the first term used to define your object/ function/ w/e is already defined) – webketje Jun 19 '14 at 19:27
  • 1
    @Tyblitz: I'm not sure what you mean. If you mean that the object could already exist, and conflict with what you add to it, that's true. It's not intended to protect against that. – Guffa Jun 19 '14 at 19:33