Nested objects in javascript, best practices - javascript

I would like to know the correct way to create a nested object in javascript. I want a base object called "defaultsettings". It should have 2 properties (object type): ajaxsettings and uisettings. I know that i can write something like
var defaultsettings = new Object();
var ajaxsettings = new Object();
defaultsettings.ajaxsettings = ajaxsettings.. etc.
But what i want to know is how to type it this way (that i suppose is a more correct way of doing it):
var defaultsettings = {
var ajaxsettings = { ... }
};
I suppose you get the idea. Thanks!

If you know the settings in advance you can define it in a single statement:
var defaultsettings = {
ajaxsettings : { "ak1" : "v1", "ak2" : "v2", etc. },
uisettings : { "ui1" : "v1", "ui22" : "v2", etc }
};
If you don't know the values in advance you can just define the top level object and then add properties:
var defaultsettings = { };
defaultsettings["ajaxsettings"] = {};
defaultsettings["ajaxsettings"]["somekey"] = "some value";
Or half-way between the two, define the top level with nested empty objects as properties and then add properties to those nested objects:
var defaultsettings = {
ajaxsettings : { },
uisettings : { }
};
defaultsettings["ajaxsettings"]["somekey"] = "some value";
defaultsettings["uisettings"]["somekey"] = "some value";
You can nest as deep as you like using the above techniques, and anywhere that you have a string literal in the square brackets you can use a variable:
var keyname = "ajaxsettings";
var defaultsettings = {};
defaultsettings[keyname] = {};
defaultsettings[keyname]["some key"] = "some value";
Note that you can not use variables for key names in the { } literal syntax.

var defaultsettings = {
ajaxsettings: {
...
},
uisettings: {
...
}
};

var defaultSettings = {
ajaxsettings: {},
uisettings: {}
};
Take a look at this site: http://www.json.org/
Also, you can try calling JSON.stringify() on one of your objects from the browser to see the json format. You'd have to do this in the console or a test page.

Related

JAVASCRIPT: Push object to array [duplicate]

I'm trying to create a dictionary object like so
var obj = { varName : varValue };
What I'm expecting is if varName='foo', the obj should be {'foo', 'some value' } however what I see is {varName, 'some value'} the value of variable is not being used but a variable name as a key. How do I make it so that varible value is used as key?
Try like this:
var obj = {};
obj[varName] = varValue;
You can't initialize objects with 'dynamic' keys in old Javascript. var obj = { varName : varValue }; is equivalent to var obj = { "varName" : varValue };. This is how Javascript interprets.
However new ECMAScript supports computed property names, and you can do:
var obj = { [varName]: varValue };
Starting with ECMAScript 2015, which has gotten better browser support in the last year(s), you can use the variable index notation:
const obj = { [varName] : varValue };
This is syntactically the same as
var obj = {};
obj[varName] = varValue;
You can also use expressions or Symbols as property key:
const contact = {
company: companyName,
};
const companiesWithContacts = {
[contact.company.toLowerCase()]: true
};
const myList = {
[Symbol.iterator]: createIteratorForList
};
function createIteratorForList() { ... }

javascript object literal instantiation

I am new to js oop and i dont understand how i can do this.
i have
var Cadastro = Object.create(QForm);
var options = {
myInstanceName: "Cadastro",
dependentListsMode: "one",
defaultButtons: ['enter-query', 'new']
}
Cadastro.initForm(options);
then i have QForm.js
var QForm;
QForm = {
initForm: function (parms) {
$.extend(this, parms);
var frmObj = $(this.formId);
this.userRestrictions(parms);
$(this.currentForm).find("a[data-form-action]").hide();
this.clearForm();
this.disableFields();
},
The problem is that if i have e object in the same page , this.currentForm have the value of the latest intantiated object .
QForm.js is very extense file with lot of methods. How can i manage this. Thanks
In general your code works, it uses Object.create to create new instances based on the QForm prototype and new instances do not share the properties, here is a short working example:
var QForm;
QForm = {
initForm: function (parms) {
$.extend(this, parms);
this.frmObj = $(this.formId);
}
};
var cadastro = Object.create(QForm);
var options = {
myInstanceName: "Cadastro",
formId: "CadastroForm",
dependentListsMode: "one",
defaultButtons: ['enter-query', 'new']
}
cadastro.initForm(options);
var formTwo = Object.create(QForm);
var options = {
myInstanceName: "FormTwo",
formId: "test",
dependentListsMode: "one",
defaultButtons: ['enter-query', 'new']
}
formTwo.initForm(options);
alert(cadastro.formId);
alert(formTwo.formId);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
If you run it, you will see CadastroForm and then test, so two instances created based on the QForm have different formId properties.

In JS, how to declare a value for an object and have all parent keys automatically be created?

myObject = {};
myObject.property1 = "123"
Typing myObject.property1 returns 123
mySecondObject = {};
mySecondObject.property1.value.type.price = "456"
returns TypeError: Cannot set property 'value1' of undefined because all or some parent keys haven't been defined yet, so you have to do something like:
mySecondObject = {};
mySecondObject.property1 = {};
mySecondObject.property1.value = {};
mySecondObject.property1.value.type = {};
mySecondObject.property1.value.type.price = "456"
Is there a method in JS that allows you to just declare an object with as many keys as you want and automatically creates all the parent keys? I couldn't find anything in Underscore.
There's no (standard) function for doing this.
An alternate initialiser is this:
var mySecondObject = { property1: { value: { type: { price : "456" } } } };

How to set a prototype for a JSON object?

I am receiving some JSON object from the server, and I want to 'typecast' or 'bless' it to an object with already defined methods. Is there any way to set a prototype for a plain JSON object?
function MyClass(someValue) {
this.myProperty = someValue;
}
MyClass.prototype.someMethod = function() { return "Here's " + this.myProperty + "!"};
var json = {myProperty : 'someValue'};
// ??? json.prototype = MyClass doesn't work, of course.
var result = json.someMethod();
How can I do that?
Well, I can suggest to try out these:
By adding the needed functions to ALL Javascript objects (bad practice)
Object.prototype.lol = function() { alert(this.a); };
var x = {a : 'b'};
x.lol();
By "extending" JSON with a function:
var json = {a : 'b', b : 123};
function extend(obj) {
obj.func1 = function(param) {
alert(this[param]);
}
}
extend(json);
json.func1('b');
By "making" the object into a function:
var json = {a : 'b', b : 123};
function extendToFunc(obj) {
var theLibrary = function(obj) {
/**
* The same as above.
*/
this.func1 = function(param) {
alert(obj[param]);
}
};
return new theLibrary(obj);
}
var jsonFunc = extendToFunc(json);
jsonFunc.func1('b');
Or you can use a JS framework for that. Or any other method that you can think of :) My examples are easy, they can be extended into anything sophisticated you need.
OK. Here is the answer (which is IE-incompatible):
json.__proto__ = MyClass.prototype;
Thankfully, I don't need no %$#$%# IE in my application.
(When I do, there is another possibility: create a wrapper function in MyClass prototype which copies all properties from JSON to the new object; shallow-copying should be enough).

Is this a safe way to reference objects in JavaScript?

If I were to define two objects myDataStore and myDrawer something like this:
var myDataStore = function(myObjectRef) {
this.myInternalObject = myObjectRef;
};
var myDrawer = function(myObjRef) {
this.myInternalObject = myObjectRef;
};
And if I were to create an object like so:
[[EDIT - Adjusted Object Creation to Ensure 'this' is being mapped to myObject, not the global window object]]
(function(){
var myObject = window.myObject = function(){
this.dataStore = new myDataStore(this);
this.drawer = new myDrawer(this);
}
})();
Then myObject.dataStore.myInternalObject, and myObject.drawer.myInternalObject, would simply be pointers back to the original 'myObject' - not taking up any additional memory in the browser. Yes?
I am interested in implementing techniques like this - as it makes it easy for objects to communicate with each other.
Nope. this refers to whatever is on the left hand side of the . or if there is no left hand side of the . then it's the global object.
So if you did this:
var MyObj = {
"create": function() {
var myObject = {
dataStore = new myDataStore(this);
drawer = new myDrawer(this);
};
}
};
MyObj.create();
this would be MyObj. If you did this:
var myObject = {
dataStore = new myDataStore(this);
drawer = new myDrawer(this);
};
(not in a function) this would be window (assuming this is in a browser).
Yes, your assumption is correct. myInternalObject will be a reference and not a new object. You can test it like this:
var MyDataStore = function(myObjectRef) {
this.myInternalObject = myObjectRef;
};
var data = {
value: "value"
};
var dataStore = new MyDataStore(data);
data.value = "test";
console.log(dataStore.myInternalObject); // logs { value : "test" } instead of { value: "value" }
No. myObject.dataStore.myInternalObject and myObject.drawer.myInternalObject will both point to the global object (mapped to window in browsers), unless you're inside a function already when you declare myObject. In other words, it will be set to whatever this is in the context in which you declare myObject. It won't be myObject itself.

Categories

Resources