0

Every time I see JS namespacing referenced it is implemented with an object expression. If I want to be sure that my namespace exists before it is assigned any properties, can I instantiate it by way of function declaration?

e.g.;

function namespace() {}

vs

let namespace = {};

The former being hoisted, and guaranteeing that properties I append to my namespace won't encounter an "undefined" error.

I know it works at least for my basic tests, but are there pros/cons to this?

Edit: Another example: https://jsbin.com/nuquxuxinu/edit?js,console

Edit: Bergi provided some good clarification, but I still need to be convinced as to why using a function as a namespace is a bad idea.

ANSWER: Since my question was marked as "opinion based" I can only deduce that there is no technical reason why you shouldn't use a function for a namespace.

Kyle
  • 63
  • 1
  • 7
  • 1
    I have no idea what the question / problem is? – Jonas Wilms Dec 07 '17 at 20:57
  • Those two things are significantly different, and in particular the `{ }` braces mean significantly different things. That is, the bracketed stuff in the first case is a function body, and in the second case is the properties of an object initializer. – Pointy Dec 07 '17 at 21:00
  • The question is: Is it OK to use a function declaration to create a namespace in Javascript as opposed to creating an object. The advantage of the function declaration is that it is hoisted, and will be evoked before I try and append any properties to the namespace? – Kyle Dec 07 '17 at 21:00
  • I understand that an object and a function is not the same thing. I'll add a jsbin as further example. – Kyle Dec 07 '17 at 21:07

1 Answers1

1

No, you should not make your namespace object a function object unless you need it to be callable. If the function does nothing (like in your example), don't use a function.

Hoisting does not have any benefits for you. The variable declaration let namespace is hoisted just as well. What is actually important is that the members of your namespace are created before you use them, and they are created by assignment. Just put them in the right order in your file - first the namespace object instantiation, then the properties of that object (if they were not already created as part of it in an object literal), last the code that uses the namespace.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • Ok, thanks for the article link. I now see that all declarations are hoisted, just function expressions are not. My question, then, is why can't I assign properties to an object (which has been hoisted) before that object is declared? – Kyle Dec 07 '17 at 21:35
  • I think I found my answer here: https://stackoverflow.com/a/43031455/366029 "Property accessors return the result of a hash lookup on the parent object." So while the object is hoisted, its property that I am trying to assign is not cannot be. That makes sense. I still am waiting for a sounder argument as to why I should never use a function as a namespace. – Kyle Dec 07 '17 at 21:38
  • Only variable declarations are "hoisted" so that the variable is available in the whole scope - their initialisations are not. I don't see why you would want to assign properties to an object before creating that object. Just put your statements in the correct order. – Bergi Dec 07 '17 at 21:43
  • Ok, I think I am getting it now. All variable declarations (var, let, const) are hoisted and can be assigned in line before their declarations. But you cannot reference unassigned hoisted variables in line before their declarations because, as you mention, their initializations are not hoisted. Function declarations are hoisted, including everything within their block. Your "Just..." statement is still irrelevant to the question. Why is it a bad idea to use a function as opposed to an object for namespacing? – Kyle Dec 07 '17 at 22:48
  • Because it's unnecessary. There is no advantage from hoisting - you still cannot use your module before it is completely initialised with all properties. You could also use a `class {}`, or a `new Map`, or an array `[]` - they're all objects and can hold properties. But you would use them either. It's confusing the reader, and technically it needs more memory and confuses the optimiser. – Bergi Dec 07 '17 at 23:07
  • The only relevant argument there is about the optimizer. If you had some some examples/explanation as to why it would "confuse the optimizer" I would definitely be interested in reading it. That would essentially answer my original question. – Kyle Dec 07 '17 at 23:16
  • It's the same argument why we don't introduce variables in our codebase that are never used anywhere. They can't hurt anything, right? – Bergi Dec 07 '17 at 23:21
  • Well if you want to stop reading and just start trolling I guess we are done. You are only strengthening the argument that there is no technical reason against using a function as a namespace. – Kyle Dec 07 '17 at 23:32
  • @Kyle My whole answer tries to make the point that there is no important technical advantages or disadvantages, but that there are non-technical disadvantages. I'm not trying to troll you, I'm just trying to explain the non-technical disadvantages which you seem to be inclined to ignore. – Bergi Dec 07 '17 at 23:35
  • I am ignoring them. I'm just looking for technical justifications one way or another to help me make a decision about which to use. If it really is only "opinion based" then just repeating that one way is wrong doesn't make any sense. You might not encounter situations in your programming where it might be useful, but that doesn't mean that legitimate situations don't exist. I just wanted to know if anyone had insight as to why you shouldn't use a function as a namespace container. – Kyle Dec 08 '17 at 02:00