What is the convention for dynamically creating an object instance? - javascript

I'm creating a page that will allow you to put multiple widgets on it, and some widgets can be duplicated on the page. So I need to understand the proper convention for creating an object instance on the fly.
// my bulb object
var bulb = {
state: 0
};
// programatically, hard-coded instance name of 'bulb1'
var bulb1 = new bulb();
$('button').click(function() {
// create another new bulb instance here with dynamic name
});
Or am I just going down the wrong path all together?
Thanks.

In JavaScript, we use functions (so called constructor functions) to instantiate object instances.
function Bulb() {
this.state = 0;
}
// one instance
var bulb1 = new Bulb();
// another instance
var bulb2 = new Bulb();
Your code doesn't work because your bulb is a regular object and not a function, so you cannot call it (which you are trying to do with bulb()).
Update: You could store your instances into an Array global variable:
var bulbs = [];
And then, whenever you create a new instance, just just make sure that you put it in the Array.
$('button').click(function() {
var bulb = new Bulb();
// do stuff with bulb
// make sure to store it into the Array
bulbs.push(bulb);
});
You can access the instances at any time like so:
bulbs[0] // the 1. instance
bulbs[1] // the 2. instance
// etc.

Related

How to use a dynamic variable in JavaScript?

I need to create something like :
var term = new Terminal();
each time I click on a button. I have found that we can create dynamic variable like this in JavaScript:
window["term_" + _idContainer] = new Terminal({
cursorBlink: true,
});
But I'm not sure about this because I can only use the last one that I create.
So someone could tell me if it really create dynamic var and if they aren't overwritten each time we create one.
You could use an object, without polluting the global space, like
var collection = Object.create(null); // empty object without prototypes
// use
collection["term_" + _idContainer] = new Terminal({ cursorBlink: true });
JavaScript objects are effectively dictionary-style objects. Therefore, you can add a property to any object in these two ways:
myobj.newProp = 'I am new!';
myobj['newProp2'] = 'So am I';
And therefore, yes, what you are doing is creating a sequence of new properties on the window object. There is no reason the one would overwrite the other, unless you neglected to increment _idContainer.
I should add that adding variables to the window object is not a popular thing to do and you could be adding many with this mechanism. Perhaps better would be to just add one, and expand it as needed:
window.termList = {};
// Then, in a loop or whatever
window.termList[_idContainer] = new Terminal({cursorBlink: true});

Javascript / Node Js - Create New variable for each instance

I'm creating a game bot on telegram using node js.
Currently I'm facing a problem on shared variable (module.exports). I'm storing some of the data on the variable. And the problem is, the shared variable index always change. For example, please refer to my code below
var sharedVar = [];
createNewRoom = function(res) {
var index = sharedVar.length;
sharedVar.push({ groupId : res.chat.id }); // every time this function is invoked, it will create a new array inside sharedVar object
//Here comes the problem, it's about the index,
//because I'm using sharedVar to store arrays, then it will become a problem,
//if one array is deleted (the index will change)
var groupId = sharedVar[index].groupId; // it runs OK, if the structure of array doesn't change, but the structure of array change, the index will be a wrong number
}
As you can see, i got callGameData function, when i call it, it will show the last value of sharedVar, it's supposed to show the current room values / data.
As i mention on the code above, it's all about the dynamic array in the sharedVar object, the index will change dynamically
Any thoughts to tackle this kind of issue? I was thinking about using a new sharedVar object everytime the createNewRoom function is invoked, but the thing is, i have to use sharedVar in many different function, and i still can't figure it out on using that method.
EDIT
This is the second method
var gameData = undefined;
createNewRoom = function() {
this.gameData = new myConstructor([]); // it will instantiate a new object for each new room
}
myConstructor = function(data) {
var _data = data;
this.object = function() {
return _data;
}
}
callGameData = function() {
console.log(gameData);
}
An array is fundamentally the wrong data type to use if you want to keep indices the same even in the face of removing entries.
A better method is to use properties of an object. For example:
var roomCache = { nextId: 1 };
createNewRoom = function(res) {
roomCache[roomCache.nextId++] = {groupId: res.chat.id}; // Add a new object to the cache and increment the next ID
}
After adding two elements, you'll have the rooms in roomCache[1] and roomCache[2] - if you want to start at zero just change the original value of nextId. You can delete elements in this object and it won't shift any keys for any other objects - just use delete roomCache[1] for example to get rid of that entry.
This assumes there isn't a better ID out there to use for the cache - if, for example, it made more sense to lookup by res.chat.id you could certainly use that as the key into roomCache rather than an auto-incrementing number. Here's how it would look like to cache the values by the group ID instead:
var roomCache = { };
createNewRoom = function(res) {
roomCache[res.chat.id] = {groupId: res.chat.id}; // Assumes res.chat.id is not a duplicate of an already cached obhect
}
Now you could just look up by group ID in the cache.
Yes, it's definitely a problem cause you are not keeping track of the index in a logical way, you are relying on position on the array which it changes, you need something that doesn't change over time to keep consistency and supports deletition of the element without affecting the rest of the elements. You could use mongo to store the generated rooms by id or maybe redis or some kind of key value pair database to store that kind of information.

Keep spawning object every second

I have a function which adds the RandomBlock object to the scene and moves it down the screen.
function enemyPaddleMovement()
{
scene.add(RandomBlock);
RandomBlock.translateX(-8);
}
RandomBlock is made by this code:
var shapes = [LeftBlock, RightBlock, middleRightBlock, middleLeftBlock, middleBlock];
var shape = shapes[Math.floor(Math.random()*shapes.length)];`
RandomBlock = new THREE.Object3D();
RandomBlock.add(shape);
What I want to do is to keep spawning a new RandomBlock object every second and move it down the screen. Ive tried using setInterval but it only replaces the same RandomBlock object rather than creating a new object everytime.
any Help?
This problem actually doesn't involve Three.js at all; it's just that you are not making any new objects, you are reusing the same one many times. Try something like this instead:
// this line stays outside the function
var shapes = [LeftBlock, RightBlock, middleRightBlock, middleLeftBlock, middleBlock];
function enemyPaddleMovement()
{
var shape = shapes[Math.floor(Math.random()*shapes.length)];
var randomBlock = new THREE.Object3D();
randomBlock.add(shape);
scene.add(randomBlock);
randomBlock.translateX(-8);
}
Note that there are no longer any mentions of randomBlock outside the function. This is because it is an object for that one call of the function and is unique to it.
I'm assuming you wanted to pick a different shape for each new object. If you don't, then just move var shape = ... back outside the function.
You need also to store this new Object. I think that you overwrite old object that is why is recreated.
Instead of RandomBlock you can have BlockContainer which will be a list.

Augmenting properties/methods to an array?

recently, i came across a question of how jQuery acts as both a function, as well as an object. the thing that made it possible was that jQuery was actually a function (hence the $()) that was attached with properties (like $.each()).
now in my project, i would want to create a model (which technically is an array of stuff), add methods to it, and return it to a variable which will hold it. is it wise to do it like this? does it interfere with anything?
//i did it like this:
function createModel(name){
var model = internal.models[name] = [];
model.add = function(){..logic to add to the model..}
//more augmented methods here...
return model;
}
//create a model
var myModel = createModel('test');
//then i can do add
myModel.add('foo');
To add to that, I don't want to mess around with the actual Array prototype stuff. I'm doing this for the currently created array.
the model i'm making is not like Backbone.js' model which is a unit of data. It's more synonymous to Backbone.js' Collection, or a Database table.
Something in that style might do, also never start a model as an array, always take a function (constructor) and a proper object they are more flexible for that.
var model = function(data) {
this.data = data;
};
model.prototype.getData = function() {
return this.data;
};
var mod = new model({foo:'foo'});
mod.getData().foo

reinitializing javascript object's properties

In my Javascript drag and drop build app, a variety of buildings can be built. The specific characteristics of these are all saved in one object, like
var buildings = {
house: ['#07DA21',12,12,0,20],
bank: ['#E7DFF2',16,16,0,3],
stadium: ['#000000',12,12,0,1],
townhall: ['#2082A8',20,8,0,1],
etcetera
}
So every building has a number of characteristics, like color, size, look which can be called as buildings[townhall][0] (referring to the color). The object changes as the user changes things. When clicking 'reset' however, the whole object should be reset to its initial settings again to start over, but I have no idea how to do that. For normal objects it is something like.
function building() {}
var building = new building();
delete building;
var building2 = new building();
You can easily delete and remake it, so the properties are reset. But my object is automatically initialized. Is there a way to turn my object into something that can be deleted and newly created, without making it very complicating, or a better way to store this information?
You can keep initial state as a prototype on an object.
var Base = function(){};
Base.prototype={a:1,b:2};
var c = new Base();
Now, you can change value of a or b to whatever you want.
To restore, just use
delete c.a or delete c.b
You will get your initial value back.
Hope this help.
Just use a copy/clone method to restore the original state
var defaults = {
foo: "bar"
};
var building;
function reset(){
building = {};
for (var key in defaults) {
if (defaults.hasOwnProperty(key){
building[key] = defaults[key];
}
}
}
Now you can just call reset() whenever you need to have building reset.

Categories