I have a use case as follows
var myObject1 = new myObject();
and myObject should have an array which will store all the objects created of this myObject
Example:-
if create an object such as
var xyz = new myObject();
myObject.all[0] == xyz
is there any way where - when I create an object & I can push it into an array which is in the definition of same object.
You can create a property directly on the constructor function, to get the myObject.all[0] == xyz behaviour mentioned in the question. Add each object to the array from within the constructor:
function MyObject() {
MyObject.all.push(this);
// any other initialisation tasks here
}
MyObject.all = [];
var obj1 = new MyObject();
var obj2 = new MyObject();
// to access the array use MyObject.all:
console.log(MyObject.all[1] === obj2); // true
Alternatively, you can add an array to the object prototype, but still add new objects to that array from within the constructor:
function MyObject() {
this.all.push(this);
// any other initialisation tasks here
}
MyObject.prototype.all = [];
var obj1 = new MyObject();
var obj2 = new MyObject();
// to access the array:
console.log(obj1.all);
// or
console.log(MyObject.prototype.all);
console.log(obj1.all[1] === obj2); // true
(Note: in both examples, I've spelled MyObject with a capital "M", because it is a JS convention for functions intended as constructors to be capitalised. This isn't mandatory.)
Maybe something like this?
function MyObject(name){
if (!O.prototype.instances) O.prototype.instances = [];
O.prototype.instances.push(name);
}
var a = MyObject('a');
var b = MyObject('b');
console.log(MyObject.prototype.instances)
Related
I create an Object in JavaScript:
var object = {value1 : "value1", value2 : "value2"};
If I now try and count the contents of 'object.prototype' I get the result 0. If I add properties I get the correct result. Am I to take it then that 'object.prototype' is in fact empty?
Thanks!
In Javascript, by DEFAULT only "function objects" have a prototype property..
for example, none of the following have a prototype property by default -
var a = new Object();
var b = {};
var a = new Array();
var b = [];
But,
var a = function() {};
has a prototype property.. and by default -
a.prototype is {constructor : this}
If you want to iterate through all the properties you assigned to your object, you can just do it with a for..in loop:
for (var prop in object){
if (object.hasOwnProperty(prop)){
var propValue = object[prop];
// ...
}
}
If you need to count the properties, you can just increment a counter on each iteration.
Can someone explain what is happening in the code below? I'd expect toString to get called for either both foo and bar, or neither. How is literal object notation different from adding fields to an object after it is created?
function Obj(v) {
this.v = v;
};
Obj.prototype.toString= function() {
window.alert("to string called for " +
this.v);
return this.v.toString();
}
var foo = new Obj('foo');
var bar = new Obj('bar');
// toString is not called here.
var map = {foo : 'blah'};
// toString is called here.
map[bar] = "blah2";
Why do object literals not use toString() while adding to an existing object does use toString()?
http://jsfiddle.net/pByGJ/2/
The main reason that object literals don't evaluate the identifier to the left of the colon is so you're not force to quote all literal names (as you do in JSON).
Bracket notation forces you to quote property names, if you don't, it will be evaluated as a variable.
The reason toString() does get called in the second example is because bar has to be converted to a string to be used as a property name.
In your first example, you're just creating a literal object (that is the exactly the same as {"foo" : 'blah'}). So that is never using the variable foo
If you want to create an object using a variable name, you can't use literal object notation, you have to use [] which is what forces it to call toString()
Here's a function to create objects with variable names in one expression.
function obj(key, value /*, key, value, ... */) {
var obj = {};
for (var i = 0, ln = arguments.length ; i < ln; i+=2) {
obj[arguments[i]] = arguments[i+1];
}
return obj;
}
Clearer Example
The fact that your variable names and values are the same doesn't help understanding the problem. Let me suggest this code
var foo = new Obj('fooValue');
var bar = new Obj('barValue');
var map = {foo : 'blah'};
map[bar] = "blah2";
// You expect map to be {fooValue: 'blah', barValue: 'blah2'}
// But it's {foo: 'blah', barValue: 'blah2'}
To do what you need, use my obj function
// Almost as clear as literal notation ???
var map = obj(
foo, 'blah',
bar, 'blah2'
);
// map = {fooValue: 'blah', barValue: 'blah2'} Yay!!
keys in an object literal are taken as strings, not interpreted as variables. This:
var map = {foo : 'blah'};
is equivalent to this:
var map = {"foo" : 'blah'};
and this:
var map = {};
map["foo"] = "blah";
but is completely different than this:
var map = {};
map[foo] = "blah";
I'm going to be getting an array of objects and want to set instance variables inside of a class based on a property. So if I get this:
ary = [{type: 'walrus', name: 'GorbyPuff'}, {type: 'humanoid', occupation: 'KingSlayer'}]
I want to initialize an object where #walrus == ary[0] and #humanoid == ary[1]
In Ruby I could user instance_variable_set, but how can this be accomplished in the Javascripts?
I'm not sure if I get what you're trying to acchieve, but the easiest way to do this would be:
var theObj = {};
for(var i=0;i<ary.length;i++)
{
theObj[ary[i].type] = ary[i];
}
The worry here is, that by altering the ary variable you will inadvertently alter the theObj:
console.log(theObj.walrus.name);//Outputs: GorbyPuff
ary[0].name = 'Nips!';
console.log(theObj.walrus.name);//Outputs: Nips! <-- objects are passed by reference, always
If the ary variable is part of a function scope, and the resulting object is its return value, you needn't worry. But if both are part of the global scope (Which they shouldn't, it's bad practice), this becomes an issue.
I therefore propose this approach:
var obj = {};
var i;
while (ary.length !== 0)
{
i = ary.splice(0,1)[0];//removes element from array
if (i.hasOwnProperty('type'))//always best to check the property you're going to use is there
{
obj[i.type] = i;
}
}
There's nothing in JS that can do this for you, just do a loop to build the object you want:
ary = [{type: 'walrus', name: 'GorbyPuff'}, {type: 'humanoid', occupation: 'KingSlayer'}]
instances={}
for(x=0;x<ary.length;x++) instances[ary[x].type]=ary[x]
document.write(instances.walrus.name) //GorbyBuff
document.write(instances.humanoid.occupation) //KingSlayer
If you want to use that array of objects as prototypes, you can do this:
var Walrus = function(){};
Walrus.prototype=ary[0];
var aWalrus = new Walrus(); // creates a new Walrus. aWalrus.name => GorbyPuff
In Javascript the Good Parts, Douglas Crawford describes a more general way of doing it:
if (typeof Object.create !== 'function') {
Object.create = function (o) {
var F = function () {};
F.prototype = o;
return new F();
};
}
Which you can use like this:
var aWalrus = Object.create(ary[0]);
here is a example of what you want:
// the class:
function MyClass(){
// stuff
}
// the data object
var o = [
{type:"MyClass",name:"a name"}
]
// how to instantiate:
var instances = [];
for(var i=0;i<o.length;i++){
if(typeof this[o[i].type] == "function")
instances.push(new this[o[i].type](o[i].name))
}
If you create the classes in a function you need to use "this" as a reference to that function, else you can use "window"
var foo = {}
var bar = new Array();
var another = [];
Also, is it possible to add to foo like so:
foo['obj'] = new Date();
var foo = {};
foo is an object literal.
var bar = new Array();
bar is an array initialized via the Array constructor.
var another = [];
another is an array literal. Creating new arrays through literals is more efficient than doing so through the Array constructor: http://jsperf.com/new-array And it’s also much easier to type ;) I’d recommend using array literals wherever possible.
Also, is it possible to add in foo like so: foo['obj'] = new Date();
Yes. That will add a property obj to foo with the value of new Date(). It’s equivalent to foo.obj = new Date();.
foo is an object, not an array.
bar and another are arrays.
if you give foo['obj'] = new Date();, obj will become a property of foo.
var foo = {}
This is an object, not an array.
var bar = new Array();
This is array but avoid new keyword with arrays.
var another = [];
This is correct way of initializing array.
Also, is it possible to add in foo like so: foo['obj'] = new Date();
There is no associative array in JS. You can instead do:
var foo = {};
var foo['obj'] = new Date();
bar and another are the same, but:
var foo = {};
foo is not an array rather an object
foo['obj'] = new Date(); //same as
foo.obj = new Date();
the advantage of f['obj'] is that you can use non-valid identifier characters ex:
foo['test-me'] // is valid
foo.test-me //not valid
var foo = {} is for object referal,
foo = {myCar: "Saturn", getCar: CarTypes("Honda"), special: Sales}
while
var bar = new Array(); is used to create new empty array.
But var another = []; can be used to assign any array empty values as well as creates empty array.
I think for date you can use like foo[1] = new Date();
Say I have the following:
var a = '1',
b = 'foo';
How do I create an object using the above variables such that my object looks like this:
'1' => 'foo'
I'm trying to make this like an associative array. Furthermore, I want 1 to contain an array of objects. I have the variable that have the array of object; I just need to put it in 1.
Use an object literal:
var myObject = { "1" : "foo" };
or, if you want to create it from variables, create a new object then assign things.
var myObject = {};
myObject[a] = b;
Furthermore, I want 1 to contain an array of objects
JavaScript doesn't care what type the data is. b can be an array as easily as a string. (And you can use an array literal where you have a string literal in the short version)
var myObject = { "1" : [ 7, "foo", new Date() ] };
var obj = { '1' : 'foo' };
obj['1']; // returns 'foo'
or
var obj = { '1' : new Array() };
obj['1']; // returns an array
To do literally what you asked:
var a = '1',
b = 'foo',
o = {};
o[a] = b;
Quentin has the rest of the answer.
Edit
An example of assigning an object to an object property:
var foo = {bar: 'baz'};
var obj = {foo: foo};
// or
// var obj = {};
// obj['foo'] = foo;
// or
// obj.foo = foo;
alert(obj.foo.bar); // baz