I have a global namespace where developers attach object singletons, class definitions, constants, etc. Each JS file has its own crafty flavor of namespace tree initialization.

Maybe a module pattern here:

window.namespace = window.namespace || {}; 
window.namespace.utils || (window.namespace.utils = {});
(function(util){
    util.myutility = new MyUtility();
    function MyUtility(){
        return {};
    }
})(window.namespace.utils)

Something else there:

window.namespace = window.namespace || {}; 
window.namespace.util = window.namespace.util || {}; 
window.namespace.util.myutility = new (function(){
    return {};  
})

Resulting in the same code repeated over and over:

if(!window.namespace) 
    window.namespace = {};
if(!window.namespace.utils) 
    window.namespace.utils = {};
...
window.namespace = window.namespace || {}; 
window.namespace.util = window.namespace.util || {};
...
window.namespace || (window.namespace = {});
window.namespace.utils || (window.namespace.utils = {});
...
$.extend(true,window.namespace,{util:{}});

I know some transpilers optimize these automatically, but aside from that, is there a more solid approach?

share|improve this question

closed as off-topic by 200_success Oct 2 '15 at 17:10

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

up vote 4 down vote accepted
$.extend(true,window.namespace,{util:{}});

No need to drag in jQuery for this. $.extend(true, window.namespace, {util:{}}) might help you merge objects. But in the end, you're still manually building the namespace tree.

Making this worse is the fact that you're deep-copying. Deep copy duplicates everything but a few data types. IIRC, functions, regexes and dates aren't cloned. Primitives, objects and arrays are recreated. This is bad for memory.

window.namespace.util.myutility = new (function(){
  return {};  
})

This... is wrong. When you use a constructor, you don't return anything from it. Otherwise, you create an instance of the constructor, but never get that instance in the end, just the value you returned. This is no different than just doing window.namespace.util.myutility = {} minus the fact that things can hide from the closure.

window.namespace = window.namespace || {}; 
window.namespace.utils || (window.namespace.utils = {});

The problem with this approach is you're doing manually what you could have done automatically. Computers are built to do repetitive tasks for you. Why not automate the process of nesting objects? Here's one piece of code from my adventures which used it to create namespaces:

// Given a dot-separated string, it creates a hierarchy on a provided object
// or globally, and returns the last object in the name space.

function useNamespace(namespace, rootObject){
  return namespace.split('.').reduce(function(parent, child){
    // If parent isn't an object (maybe some kind of already-defined property holding a primitive), throw.
    if(!parent || typeof parent !== 'object') throw Error ('Namespace encountered a primitive');
    // Otherwise, return existing child or assign a new object as child.
    return parent[child] = parent[child] || {};
  }, rootObject || window);
}

// Adding window.foo.bar
var bar = useNamespace('foo.bar');
bar.hello = "world";

// Extending bar with boom (window.foo.baz.boom)
var boom = useNamespace('foo.baz.boom');
boom.beach = "get it now!";

// Extend boom directly (window.foo.baz.boom.topher)
var chris = useNamespace('topher', boom);
chris.lion = "tiger";

// They should live under the same object
document.write(JSON.stringify(foo));

share|improve this answer
    
useNamespace should be part of the spec! nice. Next time I'll mark pseudo-code (e.g return {};) in a comment ;) Im still wondering why "when you use a constructor, you don't return anything from it. Otherwise, you create an instance of the constructor, but never get that instance in the end" The module pattern expects objects returned from constructors. I prefer it because it eliminates scoping issues, and allows us to build classes that rely on a closure's scope chain. – Shanimal Sep 28 '15 at 16:47
1  
@Shanimal stackoverflow.com/q/9304473/575527 - and yes, that's me asking 3 years ago. – Joseph the Dreamer Sep 28 '15 at 18:21
    
Thanks! I like the this assignments. That makes perfect sense. – Shanimal Sep 28 '15 at 19:29

Not the answer you're looking for? Browse other questions tagged or ask your own question.