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.
Related
i create 2 objects:
var Documentos = new QuadForm();
var Cadastro = new QuadForm();
And initialize this objects with lot of options
Cadastro.initForm(options);
Documentos.initForm(options2);
then i try to separate the data managed by each object with getName method but after the second object, myObjectName variable is overrided.
var QuadForm;
QuadForm = function () {
this.getName = function () {
// search through the global object for a name that resolves to this object
for (var name in window)
if (window[name] == this) {
window[name] = this;
window[window[name]] = window[name];
myObjectName= name;
break;
}
},
this.initForm = function (parms) {
this.getName()
$.extend(this, parms);
if (window.myState) {
delete window.myState;
}
this.containerId = parms.formId;
this.getForm(parms);
this.workflowLabels('hide');
then i use window[myObjectName].totalRecords but as it changes to the latest object name off course cannot access data.
How can i manage this.
It's not a big problem to manage several instances, but your approach is impossible, cause you can't really find all possible instances and your code does definitely not what you expected to do.
For example you can define a variable on the constructor-object which holds all instances, and than you can use it in some cases:
var QuadForm = function (name) {
this.name = name;
QuadForm.instances.push(this);
this.showAllOtherInstances = function () {
QuadForm.instances.forEach(function (instance) {
if (instance !== this) {
console.log('name: ' + instance.name);
}
}.bind(this));
}
}
QuadForm.instances = [];
var foo = new QuadForm('foo');
var anotherFoo = new QuadForm('foo');
var bar = new QuadForm('bar');
var aThirdFoo = new QuadForm('foo');
foo.showAllOtherInstances();
/*
* Output:
*
* name: foo
* name: bar
* name: foo
*/
Out the following two ways, which format for defining object is good considering performance and usage:
//Object created with public members defined using this.
var object1 = function () {
var private_i = null;
this.public_j = null;
//public function
this.public_func = function () {
}
}
OR
//Object created with public members defined using return patterns.
var object2 = function () {
var private_i = null,
public_j = null,
//private function will be exposed from return statement.
_public_func = function () {
};
return {
public_func : _public_func
};
}
The difference between the two relates to inheritance and usage. Your object2 always creates objects directly backed by Object.prototype and doesn't require use of the new keyword; your object1 creates object backed by object1.prototype (which is in turn backed by Object.prototype) and does require use of new.
Neither is really "better" in any objective way, they are just two different ways of using JavaScript, which will have fundamentally the same performance. The first one is much more common, the second one is advocated by a small but vocal minority within the JavaScript community.
The object1 example is more typically written like this:
function Object1() {
var private_i = null;
this.public_j = null;
//public function
this.public_func = function () {
};
}
Note that the first letter in such functions is capitalized (by overwhelming convention).
The prototype thing comes into it if you're going to have functions that don't need access to private_i: You could put those on the object that will be assigned to new objects created via new Object1 like so:
function Object1() {
var private_i = null;
this.public_j = null;
//public function
this.public_func = function () {
};
}
Object1.prototype.someOtherFunction = function() {
// Doesn't use `private_i`
};
You can also use prototypes with your object2, like so:
//Object created with public members defined using return patterns.
var object2Prototype = {
someOtherFunction: function() {
// Doesn't need private_i
};
};
var object2 = function () {
var private_i = null,
public_j = null,
//private function will be exposed from return statement.
_public_func = function () {
};
var obj = Object.create(object2Prototype);
obj.public_func = _public_func;
return obj;
};
I implement a class (I call it RowsEditor) and its subclass (I call it DateRowsEditor) with the jQuery code similar to this:
function create_RowsEditor(tableId) {
var rowsEditor = {
tableId: tableId,
quit_row: function(ctl) { /*...*/ }
};
$('#'+tableId).click(function(event) {
var tr = event.delegateTarget;
rowsEditor.quit_row(tr);
});
return rowsEditor;
}
function create_DateRowsEditor(tableId) {
var rowsEditor = $.extend({}, create_RowsEditor(tableId), {
quit_row: function(ctl) { /*...*/ }
};
return rowsEditor;
}
Then I create an object of type DateRowsEditor():
var rowsEditor = create_DateRowsEditor('come'):
The trouble is that on user's click quit_row() is called with an object created by create_RowsEditor() not with the derived object created with create_DateRowsEditor() as it should.
How to do it properly in a structured and object oriented way?
I've solved the problem by adding the .init() method:
var rowsEditor = {
tableId: tableId,
init: function() {
var self = this;
$('#'+tableId).handleRowsBlur(function(event) {
var tr = event.delegateTarget;
self.quit_row(tr);
});
return this;
},
...
and creating objects like this:
/*var rowsEditor =*/ create_ComeEditor('come').init();
It is the proper way to solve my problem because this way initialization of event handlers is called only when it is should be called.
The trouble is that on user's click quit_row() is not called with the derived object
Then don't use extend for that. Just create the object, and overwrite its quit_row method:
function create_DateRowsEditor(tableId) {
var rowsEditor = create_RowsEditor(tableId);
rowsEditor.quit_row = function(ctl) { /*...*/ };
return rowsEditor;
}
in Javascript, I am creating an object like this:
var testObject = {
value: "this is my initial value",
setup: function() {
value: "foo"
}
};
Now, I would like to be able to instantiate this object, so I am trying this:
var myFirstObject = new testObject();
var mySecondObject = new testObject();
so that when I call .setup() it will change the value only for that referenced newly created object. How can I achieve this? This code does not seem to work.
You don't instantiate objects, you instantiate functions.
var testObject = function() {
this.value = "this is my initial value";
this.setup = function() {
this.value = "foo";
}
}
var myFirstObject = new testObject();
var mySecondObject = new testObject();
EDIT:
As per your comment, here's how you would bind to the DOM using functions on this object:
document.getElementById('idOfElem').addEventListener(
'click', myFirstObject.clickHandler);
Bear in mind that you won't have any guarantee that the click handler will be executed in the context of your object (i.e. in your click handler, this might not be your testObject instance). If your clickHandler intends to modify the object's instance variable in any way, it's better to ensure the context like so:
document.getElementById('el').addEventListener('click',
function() {
myObj.handleClick.apply(myObj, arguments);
});
You have numerous problems with your code. Firstly, you are trying to instantiate something, by calling a constructor function. Your testObject is not a function, so you'll cause a type error. You need to change testObject to be something along these lines:
var TestObject = function () {
this.value = "this is my initial value";
};
TestObject.prototype.setup = function () {
this.value = "foo";
};
Notice that I've used an uppercase T in that identifier... that's just best practice for a constructor function. Also notice how I've defined the setup method on the prototype. This is much more efficient than defining it as a property of the instance (with this.setup) since only one copy of the function needs to exist in memory.
Now that TestObject is a function it can be instantiated by calling it with the new operator:
var myFirstObject = new TestObject();
var mySecondObject = new TestObject();
When you call the setup method on an instance of TestObject, it will apply to that instance. In other words, the value of this inside the setup method will refer to the instance on which the method has been called:
myFirstObject.setup();
console.log(myFirstObject.value); // 'foo'
console.log(mySecondObject.value); // 'this is my initial value'
You have incorrectly defined your constructor. Try this:
function testObject() {
this.value = "this is my initial value";
this.setup = function() {
this.value = "foo"
}
};
You can then call new testObject().
The object notation your using is something you can compare with a static class.
Here is the code for what you're trying to achieve:
var testObject = function(val) {
this.value = "This is my initial value",
if (arguments[0]) {
this.value = val;
}
};
var first = new testObject(); //uses initial value
var second = new testObject("hi"); //value = hi
If you'd like to write classes using this notation take a look at this: http://ejohn.org/blog/simple-javascript-inheritance/
function yourObject(value, setup) {
return {
value: value,
setup: setup
};
}
var myFirstObject = new yourObject('a', function(){});
var mySecond = new yourObject('b', function(){});
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.