0

I learnt that you could mimic namespaces in JavaScript by scoping your classes / objects inside a function expression or an object literal. That way the containing object or function provides a namespace and scope for the contained.

But for those to work, all the contained objects have to be within the same file, right?

Because if I had two namespace / naming container objects with the same name in two different files, they would overwrite each other depending on the order in which I included the source files.

File1.js

var Automtomobiles = 
{
  function Wheel() { ... }
};

File2.js

var Automtomobiles = 
{
  function Car() { ... }
};

How do I span objects / class definitions across multiple files but keep them within a same namespace?

Water Cooler v2
  • 32,724
  • 54
  • 166
  • 336

3 Answers3

4

Make Automtomobiles as global object

File1.js

var Automtomobiles = Automtomobiles || {};
Automtomobiles.wheel = function() {
}

File2.js

var Automtomobiles = Automtomobiles || {};
Automtomobiles.car = function() {
}
Kiran Shinde
  • 5,732
  • 4
  • 24
  • 41
  • Thank you. What's that `||` and where may I read about it? Does it append all other declarations of the `Automobiles` namespace / object from all the other files and merge them into a single declaration? – Water Cooler v2 Jan 04 '17 at 08:38
  • 1
    I used || operator beacuse, no matter In what order you load your files, all should work. So if file2 is loaded first then Automobiles will be {}. and car property will be attached to it. And when file1 loads, the Automobiles will be an object with car property. If you know the first file which be loaded you can simply declare var Automobiles = {}; in that file only. Then you don't need to use || operator – Kiran Shinde Jan 04 '17 at 08:43
  • @Water Cooler v2, `||` is OR operator. – Alexandru Severin Jan 04 '17 at 08:44
  • Thank you both. I am aware of the `||` operator for its use in the evaluation of logical expressions. However, this usage is not implied. In other words, this has got to be something built into JavaScript (and fairly documented) as you cannot do this with any language that has the logical OR operator. Where may I read about this usage? – Water Cooler v2 Jan 04 '17 at 08:45
  • http://stackoverflow.com/questions/881515/how-do-i-declare-a-namespace-in-javascript – mike510a Jan 04 '17 at 08:48
  • @mike510a I read that question before asking this one. I can't see where there's an explanation of this particular usage of the `||` operator in that question. – Water Cooler v2 Jan 04 '17 at 08:51
  • @WaterCoolerv2, I don't think there is special documentation for what you want. As It is very simple as I have already mentioned in previous comment – Kiran Shinde Jan 04 '17 at 08:57
  • 1
    The statement basically performs this: var Automtobiles is equal to whatever value it had before OR if it has not been previous defined,then it is equal to an empty object identified by `{ }` Anytime you put a logical operation on to the right side of a definition like `var something = (logical operation)` then that operation is carried out and the result is used to determine the next action (in this case the logical operation was || and any object can be tested for existence by simply testing if a defiition is non-zero – mike510a Jan 04 '17 at 09:15
  • @mike510a I know and can infer very easily what it does. I wanted to read about it from the documentation. – Water Cooler v2 Jan 04 '17 at 09:23
  • 1
    https://www.kenneth-truyers.net/2013/04/27/javascript-namespaces-and-modules/ third or fourth topic – mike510a Jan 04 '17 at 09:28
1

To make them global you can use window.Automtobiles = function() or to define an static property to a type. You can use .prototype

function Person(first, last, age, eyecolor) {
  this.firstName = first;
  this.lastName = last;
  this.age = age;
  this.eyeColor = eyecolor;
}
Person.prototype.nationality = "English";

console.log(new Person("john", "smith", 20, "red"));

Note how "English" is attached to each instance of Person after using the Prototype function

For your particular case, you can define Automtobiles then prototype it..

function Automtomobiles() {

};

Automtomobiles.prototype.wheel = function() { ... }
Automtomobiles.prototype.car = function() { ... }
mike510a
  • 2,102
  • 1
  • 11
  • 27
  • I know about prototypal inheritance. My question is about splitting objects across multiple source files under a same context / namespace / naming container. – Water Cooler v2 Jan 04 '17 at 08:37
  • as long as their within the same `document` (web page) they will all be within the global namespace or whatever namespace you specify – mike510a Jan 04 '17 at 08:40
  • Oh yes, essentially the same as @Kenny's suggestion. Nice hack. So, I infer that there's no way other than to make the code a bit convoluted by either adding to an existing class' prototype or to an existing object. Thank you. – Water Cooler v2 Jan 04 '17 at 08:43
0

Using pure javascript you could use the common notation that lot of libraries use. For one file:

var Automtomobiles;
(function (Automtomobiles) {
    var Wheel = (function () {
        function Wheel() {};        
        return Wheel;
    }());
    Automtomobiles.Wheel = Wheel;
})(Automtomobiles || (Automtomobiles = {}));

And the other file:

var Automtomobiles;
(function (Automtomobiles) {
    var Car= (function () {
        function Car() {};      
        return Car;
    }());
    Automtomobiles.Car= Car;
})(Automtomobiles || (Automtomobiles = {}));

Anyway, if you are open to use third party libraries, they could help you too. Long time ago I used Dojo declare feature, which manages the namespaces and class names for you, althoug I'm sure that at current exists more libraries to reach that.

In fact, you also could use Typescript, which is perfect to reach your goal and vey use to learn. The code generated by Typescript looks like the examples I posted above.

christiansr85
  • 867
  • 19
  • 40