I am working on a legacy application and all JS seems mystrious to me.
Here is the few mysterious lines which are loaded before all and I don't have any idea what they are doing.
var i2b2 = {sdx:{TypeControllers:{},Master:{_sysData:{}}},events:{},hive:{cfg:{},helpers:{},base_classes:{}},h:{}};
if (undefined==i2b2.hive) { i2b2.hive = {}; }
i2b2.hive.tempCellsList = [
{ code: "PM",
forceLoading: true
},
{ code: "ONT" },
{ code: "CRC" },
{ code: "WORK"},
{ code: "SHRINE"},
{ code: "PLUGINMGR",
forceLoading: true,
forceConfigMsg: { params: [] }
}
];
There are many more var and if statements but they are doing same thing with different variables.
Please help me to solve this mystery.
The first line initialises i2b2 using nested object literals.
var obj = {}; is a shorter way of writing var obj = new Object();
A simple object literal will be
var simpleObject = {
property1: "Hello",
property2: "MmmMMm",
property3: ["mmm", 2, 3, 6, "kkk"],
method1: function() {
alert("my method")
}
};
A nested one will be
var rectangle = {
upperLeft: {
x: 2,
y: 2
},
lowerRight: {
x: 4,
y: 4
}
};
Yours is a classic.
var i2b2 = {
sdx: {
TypeControllers: {},
Master: {
_sysData: {}
}
},
events: {},
hive: {
cfg: {},
helpers: {},
base_classes: {}
},
h: {}
};
The second line should be IMHO
i2b2.hive = i2b2.hive || {};
This just says that if hive is undefined create a new object.
The last lines create a property tempCellsList to the object hive. ( Please note that hive in turn is a property of i2b2 )
Lastly a new array of objects are added to the property tempCellsList
This javascript code creates a variable called ib2b that has a number of properties: sdx, events, hive, etc. Those properties hold more composite objects, which are constructed below.
The idea is that this global object can be referenced from other javascript code and it stores global configuration for the client-side application.
I'm not quite sure, what exactly you don't understand. There are two "strange" points about the code above, which I'll try to explain, but if that's not enough you will need to describe better what you don't understand:
The code checks is i2b2.hive is is undefined and set it as an empty object, if it is. Since the property is obviously set in the previous line, my guess is that this code is generated dynamically and some of the logic (such as this check) is defined in the JavaScript code even if it could (should?) be the the server side code.
undefined==i2b2.hive is a bad/wrong way to test "undefinedness", because undefined is not a reserved word in JavaScript.This just works, because undefined is just a variable that - by chance - happens to be undefined. Instead one should use if (typeof i2b2.hive == "undefined") ... or just if (i2b2.hive) ....
It seems like it's setting a few parameters in that i2b2 object. It doesn't "do" anything in itself, but it seems to set a few basic configuration settings for further execution. Try and look for similar occurrences in the code further below.
E.g it sets i2b2.hive.tempCellList[5].forceLoading to true. Later on the application probably has if-conditions, such as
for(var i in i2b2.hive.tempCellList)
{
if(i2b2.hive.tempCellList[i].forceLoading === true)
{
// do something...
}
}
Related
I find that when I write javascript I encounter a situation where I am forced to write ugly code. This is due to my inability to reconcile the following two criteria:
1) Define data using shorthand, e.g. var data = { a: 1, b: { c: 2, d: 3 ... } }
2) Use a primitive operator to check for property existence
For example consider a function which returns the intersection of two Object instances' keys as an Array of the intersecting keys:
var intersection = function(obj1, obj2) {
var result = [];
for (var k in obj1) if (k in obj2) result.push(k);
return result;
};
That code looks quite nice. But unfortunately, it doesn't always work as expected! This is due to the inconsistency between for (x in y), and if (x in y): Using for (x in y) will only iterate over "own" properties (properties which return true for hasOwnProperty), while if (x in y) while apply for "own" and "non-own" properties!
If I call intersection like so:
var obj1 = { toString: 'hahaha' };
var obj2 = {};
var intersectingKeys = intersection(obj1, obj2);
I will wind up with intersectingKeys === [ 'toString' ]; Obviously this is not correct: an intersection operation involving an empty set (as obj2 appears to be) must return an empty set. While {} is clearly intended to be "empty", our problem is that ('toString' in {}) === true. This also applies to terms such as 'constructor', 'valueOf', as well as any new properties that are introduced to Object.prototype in the future.
In my opinion, if a native operator can provide iteration over keys, a native operator should be able to verify whether a key will appear in an iteration. It feels inconsistent and ugly, to me, to use a native operator for one, but a function call for the other. For that reason I dislike this fix:
var safeIntersection = function(obj1, obj2) {
var result = [];
for (var k in obj1) if (obj2.hasOwnProperty(k)) result.push(k);
return result;
};
If if (x in y) must be used, I only see one other possible solution: Ensure that the parameters passed to intersection have no properties at all, apart from properties explicitly defined by our code. In other words, ensure that we only work with prototype-less objects:
var obj1 = Object.create(null, {
toString: {
configurable: true,
enumerable: true,
writable: true,
value: 'hahaha'
}
});
var obj2 = Object.create(null, {});
var intersectingKeys = intersection(obj1, obj2);
Note that this code uses intersection, not safeIntersection, and still works because obj1 and obj2 are prototype-less. But the problem is, now data definition is really, really clunky! Look at how much code it takes to define an object with a single "toString" property. This approach prevents us from using javascript's beautiful object-shorthand. Even if we write a utility function to encompass prototype-less object creation, the definition of nested objects is still incredibly clunky:
// Utility function for prototype-less object definition
var obj = function(props) {
return Object.create(null, props.map(function(v) {
return {
writable: true,
configurable: true,
enumerable: true,
value: v
};
}));
};
// Now defining `obj1` looks ok...
var obj1 = obj({ toString: 'hahaha' });
// But for large, nested object definitions it's sooper ugly:
var big = obj({
a: 'a value',
b: 'b value',
moreProps: obj({
wheee: 'yay',
evenMoreProps: obj({
prop: 'propMeUp'
/* ... */
})
/* ... */
})
});
Javascript's object-definition shorthand is a huge perk of the language, and throwing it away by being forced to wrap all { ... } instances in a function call seems like a tremendous pity.
My ideal solution to this problem would involve converting the shorthand object constructor to produce prototype-less objects. Perhaps a global setting:
// Perhaps along with other global settings such as:
'use strict';
Error.stackTraceLimit = Infinity;
// We could also have:
Object.shorthandIncludesPrototype = false;
Although even if this solutions were available it would break tons and tons of pre-existing libraries. :(
How do I reconcile the following criteria???:
1) Write code that works
2) Use the primitive in operator to check for property existence
3) Define objects using typical shorthand
Perhaps it's impossible to meet all these criteria simultaneously. In that case, what are some of the next-best approaches for keeping code clean in these cases?
You could get first the own properties of the first object with Object.keys and filter with Object.hasOwnProperty the second object's keys.
function intersection(o1, o2) {
return Object.keys(o1).filter({}.hasOwnProperty.bind(o2));
}
console.log(intersection({ a: 10, b: 20, e: 30 }, { a: 10, c: 20, d: 30 })); // ['a']
console.log(intersection({ toString: 'hahaha' }, {})); // []
So, you've set out three incompatible requirements. You say you have to use in. You say objects have to be defined as {} so they will have a prototype. But, you don't like the way in works. And, you want code that uses those, but works differently than they are designed. Those are your two choices.
There's NO answer with those requirements. in works the way it does. You can't change it. We can't change it. Yes, it works differently based on the context, but that's how it's implemented. Deal with that by finding a practical solution to a real problem or write your own language that works the way you want the language to work.
FYI, for a real-world solution you may want to consider a Map object for storing your data and use .get(), .has() and .set() on it. Simple, clear, works.
Prior Answer BEFORE question was massively edited
First off, you can just use Object.create(null); to create a prototype-less object. So, the only properties it will have are the ones you put there.
I'd suggest that rather than accessing a property directly off the object, you just create one reusable function that checks to see if the property name is valid before returning it:
function sendValidProperty(req, res) {
var propName = req.params.propertyName;
if (Object.prototype.hasOwnProperty.call(dataObject, propName) {
res.send(dataObject[propName]);
} else {
res.sendStatus(400);
}
}
router.get('/propertyOfObject/:propertyName', function(req, res) {
sendValidProperty(req, res);
});
Or, you could encapsulate a smaller piece of it:
function getValidProperty(obj, propName) {
return Object.prototype.hasOwnProperty.call(dataObject, propName) ? obj[propName] : null;
}
router.get('/propertyOfObject/:propertyName', function(req, res) {
let val = getValidProperty(dataObject, res.params.propertyName);
if (val !== null) {
res.send(val);
} else {
res.sendStatus(400);
}
});
In either case, you don't have to repeat the checking of a property. That's in the common, shared function. FYI, when you want to use object methods on a prototype-less object, you can use the form I show above: Object.prototype.hasOwnProperty.call(dataObject, propName) instead of dataObject.hasOwnProperty(propName).
One of the main rules of server development is to NEVER trust the input you get from a request. You always have to check it or sanitize it before using it. This whole question kind of sounds like you're trying to avoid doing that. You just can't shortcut checking input and have a fully reliable server.
I have 2 extra solutions that are probably worth mentioning here:
1) Recursive obj function
As I mentioned in the question, having an obj method which creates an un-prototyped value from a regular Object defined via shorthand gets really ugly when it needs to be applied all throughout a nested shorthand structure - but this problem can be somewhat solved if the obj method is recursive, so that it only needs to be applied to the root Object and not explicitly to every inner child property:
var obj = function(val) {
if (val.constructor === Object) {
var ret = Object.create(null);
for (var k in val) ret[k] = obj(val[k]);
} else if (val.constructor === Array) {
var ret = [];
for (var i = 0; i < val.length; i++) ret.push(obj(val[i]));
} else {
var ret = val;
}
return ret;
};
var thing = obj({
prop1: 'hello',
prop2: 'hi',
prop3: [
{ num: 1, val: 'lalala' },
{ num: 2, val: 'heehee' },
{ num: 3, val: 'hoho' },
],
really: {
deep: {
property: {
over: {
here: { val: 'soooo deep' }
}
}
}
}
});
console.log('toString' in thing);
console.log('toString' in thing.prop3[1]);
console.log('toString' in thing.really.deep.property.over.here);
Now it's important that all shorthand objects are wrapped in obj.
2) Clear out Object.prototype
I've found that chrome and node (v0.12.0) will allow me to delete all properties from Object.prototype. The prototype can even be restored at any point in the future if these removed properties are kept in memory:
var savedPrototype = {};
var removePrototype = function() {
savedPrototype = {};
var props = Object.getOwnPropertyNames(Object.prototype);
for (var i = 0; i < props.length; i++) {
savedPrototype[props[i]] = Object.prototype[props[i]];
delete Object.prototype[props[i]];
}
};
var restorePrototype = function() {
for (var k in savedPrototype) {
Object.prototype[k] = savedPrototype[k];
}
};
removePrototype();
var obj = { val: 'haha' };
console.log('toString' in obj); // false
restorePrototype();
console.log('toString' in obj); // true
As jfriend00 already wrote, the question proposes constraints that are fundamentally impossible in the current versions of JavaScript. The best we can do is write some abstractions within the limitations of the language.
We've already looked at some possibilities, such as using a wrapper function (like obj() in the question). Because "universal support" is not a criterion in the question, I'll propose one solution using ES6 Proxies. We can use the has() handler method of a Proxy to alter the behavior of the in operator so that it only considers own properties:
Object.prototype.own = function () {
return new Proxy(this, {
has: function (target, propertyName) {
return target.hasOwnProperty(propertyName);
}
});
};
document.writeln('toString' in {});
document.writeln('toString' in {}.own());
document.writeln('foo' in { foo: 1 });
document.writeln('foo' in { foo: 1 }.own());
This requires a modern browser (no IE; Edge OK) or Node 6.4.0+. Of course, adding members to the prototype of Object is a risky move. We can add additional handlers to the Proxy as needed, or rewrite the implementation for ES5 and below (but this requires significantly more code).
Compatibility concerns aside, this approach satisfies the requirements of the question: we can use object literals and the in operator, and the code is concise and readable. We just need to remember to call own() when we need it.
We can rewrite the intersection() method from the question using this convention:
Object.prototype.own = function () {
return new Proxy(this, {
has: function (target, propertyName) {
return target.hasOwnProperty(propertyName);
}
});
};
var intersection = function(obj1, obj2) {
var result = [];
for (var k in obj1.own()) if (k in obj2.own()) result.push(k);
return result;
};
document.writeln(intersection({ a: 1, b: 2, c: 3 }, { b: 2, c: 3, d: 4}));
Your question could be solved with some beautiful code.
ES5
var intersect = function(obj1, obj2) {
var keys1 = Object.keys(obj1);
var keys2 = Object.keys(obj2);
return keys1.filter(function(k) {
return keys2.indexOf(k) !== -1;
});
}
ES6
let intersect = (obj1, obj2) => {
let keys1 = Object.keys(obj1);
let keys2 = Object.keys(obj2);
return keys1.filter(k => keys2.includes(k));
}
This is the JavaScript way of solving such problems. It is way better, since you don't need to use any loop. The built-in methods like filter(), indexOf() or includes() would perform better than any loop.
JavaScript really behaves weirdly in case of Objects. Although I'm not sure if it is the correct behaviour.
Inside a new Object(), I set some properties in the object. Next time when I do again new Object(), instead of default values I get values set in previous instance. Argh.
Below example explains the problem clearly
function testo() {}
testo.prototype = {
obj: {
what: {
value: 5
}
},
done: function () {
console.log(this.obj.what.value);
this.obj.what = {value: 10};
}
};
var x = new testo();
x.done();
var y = new testo();
y.done();
The output of above code is:-
5
10
I was expecting it to be:-
5
5
Why? Because I'm creating new Class() and in the previous instance I had set the value using 'this', it is not static and default properties of all objects inside it should show up.
I have created above example as the demo. I'm facing this issue in my library. I know it has to do with objects are stored as the reference.
How should I proceed to get the expected output? Any thoughts?
You could move the prototype property (which is for all instances the identical) to just a this object in the class.
function testo() {
this.obj = { what: { value: 5 } };
}
testo.prototype = {
done: function () {
console.log(this.obj.what.value); this.obj.what = { value: 10 };
}
};
var x = new testo();
x.done();
var y = new testo();
y.done();
Given the following javascript object:
var commands = {
back:{
command: "b",
aliases: ["back","go back","backwards"],
action: function(){
return this.key; //I want this to return "back" (the prop name)
},
desc: "goes back"
}
}
How can i access the Property Name which is "back" from within the action()?
I think it should be pretty simple, but if it isn't something simple than I'll add more details.
NOTE: aliases[0] is holding the name by chance, and it is not promised to hold it in the future or in other commands.
EDIT:
Sometimes we get to complicated while we can solve the problem pretty fast.
In this case i can just go ahead and return the string "back"
I'll leave the question and accept the answer that solves my question if there is such a solution.
Returning the string as you mentioned is definitely the easiest way. But I could see cases where someone might want to be able to get similar functionality with a dynamically created object in which the keys are not known until run-time.
A solution that would work in that case is exposing the commands object to the sub objects, so they can look themselves up:
var commands = {
back:{
command: "b",
aliases: ["back","go back","backwards"],
action: function(){
var commandKeys = Object.keys(commands);
for(var i=0; i < commandKeys.length; i++){
if(commands[commandKeys[i]] === this){
return commandKeys[i];
}
}
},
desc: "goes back"
}
};
In this case it may also make more sense to share the function across all those action objects:
var commands = {
back:{
command: "b",
aliases: ["back","go back","backwards"],
action: getAction,
desc: "goes back"
},
forward: {
//...
action: getAction,
//...
}
};
function getAction() {
var commandKeys = Object.keys(commands);
for(var i=0; i < commandKeys.length; i++){
if(commands[commandKeys[i]] === this){
return commandKeys[i];
}
}
}
Unless you need to perform some specific logic for each sub object.
EDIT: To improve efficiency, we can make it where the getAction function is not executed every call and add a property that will store the name. That way the lookup only occurs the first time.
var commands = {
back:{
command: "b",
aliases: ["back","go back","backwards"],
action: getAction,
desc: "goes back"
},
forward: {
//...
action: getAction,
//...
}
};
// Only needs to getKey the first time called.
function getAction() {
if(!this.key) this.key = getKey(this);
return this.key;
}
function getKey(obj) {
var commandKeys = Object.keys(commands);
for(var i=0; i < commandKeys.length; i++){
if(commands[commandKeys[i]] === obj){
return commandKeys[i];
}
}
}
When you call action as the following:
commands.back.action();
the scope of action is back. Sadly, the creation of the object that gets assigned to commands.back does not know that this inside of action is called "back". From my understanding, this is done because we could assign the object assigned to commands.back to another object with another name. As in:
var foo = { f: function(){console.log(this) } };
var bar = foo;
bar.f();
Or closer to what you have...
var foo = {
bar: {
f:function(){console.log(this)}
}
};
var other = { another: (foo.bar) };
The only way I know of where the object knows the name of what it was created within are functions. So, we can create a temp function that has the name back that will create an object as desired.
var commands = {
back:(new function back(){
// I prefer to assign to a variable to assist with the readability as to what "this" is:)
var self = this;
self.command = "b";
self.aliases = ["back","go back","backwards"];
self.action = function(){
// Can leave as "this" or change to "self".
return this.key;
};
self.desc = "goes back";
self.key = self.prototype.constructor.name;
})
}
Simplest Solution
But at that point might as well just add a property that already has the name. I would recommend doing a property called key or name rather than placing the name directly into the action function to make it easier to have multiple places where the name is used. Also, allows there to be a single place to change the name within the object if need be.
var commands = {
back:{
command: "b",
aliases: ["back","go back","backwards"],
action: function(){
return this.key;
},
desc: "goes back",
key: "back"
}
}
EDIT: Added this edit as another way to do this, but I would still do the previous way. We can utilize Object.keys to get the name of the property since back is being added as an enumerable property of commands.
var i = 0,
commands = { back: {
key: (function(id){return function(){return Object.keys(commands)[id]}})(i++)
}}
Then can get the key by the following:
commands.back.key();
Or within the action function as:
this.key();
Can add key to back as a get which would look like:
var i = 0,
commands = { back: {
id: (i++),
get key() {return Object.keys(commands)[this.id]}
}}
This will allow you to access the property as commands.back.key and within the action function as this.key.
Can also pre-define everything then can do the following:
var i = 0, commands = { back: undefined };
commands.back = { key: Object.keys(commands)[i++] };
You can add and also advisable to add a toString method for your every object like this.
var commands = {
back:{
command: "b",
name : "back",
aliases: ["back","go back","backwards"],
action: function(){
return this.toString();
},
desc: "goes back",
toString : function(){
return this.name;
}
}
}
console.log(commands.back.action()); // back
console.log(commands.back.toString()); // back
What you are having here, is a nested object, held on the property of an object.
You can not get that property by hand - unless you are doing some strange metaprogramming stuff, such as getting the AST parent node and trying to determine the property the object is held etc. The easiest way, is to hold the property name using a string i.e.: "back".
In simple terms, it is like holding the object to a var
var obj = {/*....*/};
And you are trying to get the var name from within the object.
Remember though that in JavaScript, you can access an object property, using both string and index notation, so commands.back can also be called using commands['back']. If I am guessing right, you are trying to make a sort of dispatching, so this notation can be useful for you.
If you've got that object (literal object) you can't use this keyword. You have two solutions:
return commands.back.aliases[0]
Or otherwise,you can construct the object as a prototype object and not literal object:
var commands = function() {
this.back = function() {
this.command = "b";
this.aliases = ["back","go back","backwards"];
this.action = function() {
return this.aliases[0];
};
this.desc = "goes back";
};
};
And initialize like this
var instance = new commands();
instance.action(); // it returns "back" string
I am using jQuery and I am still pretty new to JavaScript. I am implementing an object as the following:
MyObject = {
properties : [{}],
resetProperties: function resetProperties() { this.properties = [{}] }
};
As you can see in the above code I can reset the properties by running MyObject.resetProperties() but, in order to do that, I state two times the [{}] variable. How should I accomplish the same thing without repeating that code?
Update
I tried to do the following:
MyObject = {
properties : this.propertiesDefault,
resetProperties : function resetProperties() { this.properties = [{}] },
propertiesDefault: [{}]
};
but I get "TypeError: invalid 'in' operand MyObject.properties" and I am not sure that is the right way to proceed.
It seems to me that it would be impossible to avoid having your default / reset properties as a separate object to the one that will be modified.
I would recommend having a default value, and cloning it in your initialisation and reset function. Since you tagged your question with jQuery, I assume you are happy to clone the object with that:
MyObject = {
defaultProperties : [{}],
properties : jQuery.extend(true, {}, this.defaultProperties),
resetProperties: function() {
this.properties = jQuery.extend(true, {}, this.defaultProperties);
}
};
See this Stack Overflow question for more information on cloning objects:
What is the most efficient way to deep clone an object in JavaScript?
This is the documentation for jQuery.extend:
http://docs.jquery.com/Utilities/jQuery.extend
From what I know this isn't possible. You're going to have to hard-code the property reset. I tried setting a variable cache outside the object, but when I reset the property it unfortunately maintains its value.
var obj = {
p: [ {} ],
r: function() { this.p = this.cache; }
};
obj.cache = obj.p; // attempt to set to original
obj.p[0].m = 5; // modify
obj.r(); // reset
--------
>>> obj.p[0].m; // 5
We can assume the the cache property is being modified in the same way as p is. Therefore, we can't reset like that.
Depends on what you want. Since you're new to javascript, you may be unfamiliar with using functions to create custom objects, which is the general javascript "OOP" kinda way to do it.
function MyObjectClass() {
this.properties = null;
this.resetProperties();
}
MyObjectClass.prototype.resetProperties = function () { this.properties = [{}] };
var MyObject= new MyObjectClass();
But we don't really know that function MyObject needs to fulfill. There may be a requirement that it NEEDs to be a plain old javascript object. Or maybe not, and you're done.
Of course, you can always directly:
MyObject = {
properties : null,
resetProperties: function () { this.properties = [{}];}
};
MyObject.resetProperties();
Here's a sample of my structure:
this.is.a.really.long.namespace = {
inputs : {},
buttons : {},
panels : {},
fn : {
abc : function() {},
def : function() {}
}
};
Now, as you can see I'm storing my inputs, buttons, panels, and functions in their own respective object literals. The issue lies within fn.abc, fn.def, or any other function inside of page.fn. I want to be able to access my inputs, buttons, and panels from within the functions inside of fn.
Obviously, I know I can type this.is.a.really.long.namespace.inputs, but as you can see, that's pretty long, and I don't want to have to type it out for every single instance where I need to reference an object within the page.
Is there not a way I can directly reference inputs, buttons, and panels from within fn?
I was thinking I could do:
fn : {
that : this.is.a.really.long.namespace,
abc : function() {},
def : function() {}
}
which would allow me to use that.inputs inside of fn.abc, but is there a concern with that method? Any sort of overhead I need to be aware of? Or is there a better way to accomplish this?
There is nothing wrong with this. In fact you are likely to reduce overhead for the following reasons:
Less run-time resolution of object heirarchies
Fewer characters = shorter script
A more fleshed out construct is the commonly used "module pattern."
Javascript is fairly inefficient internally (e.g. it doesn't have real indexed arrays) so anything you can do to reduce run-time lookups is usually good. Creating a pointer to a long heirarchy will be much faster than using the full heirarchy every time. This will probably only matter much in long loops, but since it's also easier to read, it's just a bonus of being a bit faster - there is no downside.
(edit)
to do this with straight objects you could do something like this, using jQuery to
simplify adding properties:
this.is.a.long.namespace = {};
$.extend(this.is.a.long.namespace,
{ that: this.is.a.long.namespace,
... // other properties
});
Generally speaking though if you're building functional objects the module pattern is better, because it's more flexible and lets you use scope to create private variable/objects.
this.is.a.long.namespace = (function()
{
var that = {},
somePrivateVariable;
function privateFunction() {
...
}
that.inputs = {};
...
// assign everything to "that"
return that;
}());
If you build the object in such a way that every level contains a parent parameter pointing to the level above it, then you can access the data that way. Take a look at this similar question.
Ok ... Here's what I ended up doing:
this.is.a.really.long.namespace = {
inputs : { firstName : undefined },
buttons : { submit : undefined },
fn : {
root : undefined,
abc : function() { console.log(this.root.inputs.firstName); },
def : function() { console.log(this.root.buttons.submit); }
},
init : function() {
var self = this,
fn = self.fn,
inputs = self.inputs,
buttons = self.button;
fn.root = this; // this is the key
inputs.firstName = $("#first-name");
buttons.submit = $("#submit-button");
fn.abc();
fn.def();
}
};
I would consider something like this:
var namespace = this.is.a.really.long.namespace
this.is.a.really.long.namespace = {
root : namespace,
inputs : {},
buttons : {},
panels : {},
fn : {
abc : function() {},
def : function() {}
}
};
from there you should have no problems referencing your namespace anywhere within the object.