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});
Related
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.
Experiencing a weird Javascript bug it'd be great to get some insight to. I've managed to debug it to know what the issue is, I just haven't been able to figure out the why yet and a non-hackey way to resolve it.
I'm trying to create a new instance of an array as a variable inside a function, so I can manipulate it without affecting the main array. Instead I'm getting some kind of reference, so doing operations on my new variable ids also affects the array that ids equals.
I've simplified my code to demonstrate the issue more clearly:
var defence = {
selectedIDs: new Array(),
toggleTerm: function(term, id) {
// add to the main array
this.selectedIDs.push(5);
// adds to this.selectedIDs
this.showTweet();
},
showTweet: function() {
// copy the array as a new variable in the scope of the function
var ids = this.selectedIDs;
if (ids.length == 1) {
ids.push(10); // this pushes to 'ids' AND 'this.selectedIDs'
}
console.log(this.selectedIDs); // outputs [5, 10]
}
}
Also in JSFiddle
It's always been my understand that var ids = this.selectedIDs would effectively copy the contents of this.selectedIDs into that new instance - however this doesn't seem to be the case.
Any ideas on why this is happening, and the best way to get around it (beyond manually recreating it through something like a for loop)?
It's always been my understand that var ids = this.selectedIDs would
effectively copy the contents
OK, but your understanding is wrong. It's an assignment.
Consider this instead:
var ids = this.selectedIDs.slice()
It's always been my understand that var ids = this.selectedIDs would
effectively copy the contents of this.selectedIDs into that new
instance - however this doesn't seem to be the case.
I don’t know how to describe this except “no, that doesn’t happen at all”. JavaScript isn’t C++; when you assign something to a variable, it is never copied. You always get a reference, except in the case of primitives, which are immutable, making the point moot. (Heh.)
You could use concat, but if this isn’t the actual situation, there might be something more appropriate.
showTweet: function() {
var ids = this.selectedIDs;
if (ids.length === 1) {
ids = ids.concat(10); // Array.prototype.concat returns a new array
}
console.log(this.selectedIDs); // outputs [5]
}
Let's say there is a simple object literal which name will never change:
var car = {
wheels : 4,
construct : function() {
var that = this;
setTimeout(function() {
console.log(that.wheels);
console.log(car.wheels);
}, 500);
}
};
My question is: Which way is better? Referencing by the object's name or creating a new variable (which may take some time and memory and probbaly must be done in multiple functions)?
Within the object, you should always refer to the object via this (or a copy of it, e.g. that, if required) to prevent the following breakage:
var car = ...
// do stuff
car = undefined; // or anything else, perhaps by a code hacker in the JS console
// class is now broken
You should treat the variable name that happens to have been given to your object on the outside as unknown to you, and subject to change.
Someone else might call it something else, there might be multiple names, the name might suddenly point at some other object altogether. Such variables are for the benefit of the "owners" of references to the object, and not for the object itself.
Does anyone know whether there are any performance trade-offs/advantages to assigning an object's fields at creation rather than later e.g.
var exObj = new exampleObject(name, date);
OR
var exObj = new exampleObject();
exObj.name = "blah";
exObj.date = "blah";
(assuming you've created your class accordingly)
Also, as a side thought, given that JS arrays are stored as objects, am I correct in assuming that there are no performance differences between using one over the other ? (For some reason using an array with a numeric index "feels" faster.)
Cheers
N
Test it yourself - http://jsperf.com/assign-object-fields-at-creation-or-later
is there a way to copy a global object (Array,String...) and then extend the prototype of the copy without affecting the original one? I've tried with this:
var copy=Array;
copy.prototype.test=2;
But if i check Array.prototype.test it's 2 because the Array object is passed by reference. I want to know if there's a way to make the "copy" variable behave like an array but that can be extended without affecting the original Array object.
Good question. I have a feeling you might have to write a wrapper class for this. What you're essentially doing with copy.prototype.test=2 is setting a class prototype which will (of course) be visible for all instances of that class.
I think the reason the example in http://dean.edwards.name/weblog/2006/11/hooray/ doesn't work is because it's an anonymous function. So, instead of the following:
// create the constructor
var Array2 = function() {
// initialise the array
};
// inherit from Array
Array2.prototype = new Array;
// add some sugar
Array2.prototype.each = function(iterator) {
// iterate
};
you would want something like this:
function Array2() {
}
Array2.prototype = new Array();
From my own testing, the length property is maintained in IE with this inheritance. Also, anything added to MyArray.prototype does not appear to be added to Array.prototype. Hope this helps.
Instead of extending the prototype, why don't you simply extend the copy variable. For example, adding a function
copy.newFunction = function(pParam1) {
alert(pParam1);
};