JavaScript Object Creation and its Prototype - javascript

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.

Related

Array insertion JavaScript

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)

javascript access object with variable name

I am trying to access an object but the name is variable. So:
I have object41, object42 and object43. I want to access object42.
id = 42;
something like this:
object+id.function();
I have searched and found how to assign objects with variable names and how to access properties with variable names but I can't figure out how to access objects with variable names.
Is this something obvious that I am missing?
If these objects are global, you can access them via the window object, and then call your function on the resulting object.
var id = 42;
window["object" + id].function();
Try using eval
// Sample object
function X(id) {
this.value1 = "A" + id;
this.function = function f(value){
alert(value);
};
return this;
}
// n number of object created
var object1 = new X(1);
var object2 = new X(2);
// iterate over all object
for (i=1; i<=2; i++) {
var expr = "object"+i+".function(object"+i+".value1)";
eval(expr);
}
Here a jsfiddle : demo

Unexpected result pushing objects into an array

How to iterate over an array of literal objects in JavaScript?
I would like to do something like that:
grupo = []; // declare array
text = {}; // declare new object
text.a = "texta"; // declare property "a" of an object.
text.b = "textb";
grupo.push(text); // add object to array
text = {}; // declare new object
text.a = "textc"; // declare property
grupo.push(text); // add object with other property
// Iterate over
for (i=0; i<=grupo.length; i++) {
console.dir(grupo[i].text.a);
}
There are various errors in that code:
You're putting the same object in the array twice, not putting two objects in the array. After you push text into the array, you're just overwriting the a property on the same object and pushing it again. You haven't created a new object.
You haven't declared any of your variables (everywhere you've said "declare" in your comments, those are not declarations), so you're falling prey to The Horror of Implicit Globals. Use var to declare variables.
A line comment should start with //, not \\ (those cause a syntax error)
The for loop at the end should use <, not <=, for its termination condition. For the various ways to loop through arrays in JavaScript, see this question and its answers.
Here's a cleaned-up version of that code:
var text, grupo, i; // Declare variables
text = {}; // Create an object and assign it to the variable
grupo = []; // Create an array and assign it to the variable
text.a = "texta"; // Set the property `a` on the object
text.b = "textb"; // Set the property `b` on the object
grupo.push(text); // Put that object onto the array
text = {}; // Create a second object
text.a = "textc"; // Set the property `a` on that new object
grupo.push(text); // Put that object on the array
for (i=0;i<grupo.length;i++) {
// ^-------------------- Note no =
console.dir(grupo[i].text.a);
}
Do you mean something like this?
for (var key in validation_messages) {
var obj = validation_messages[key];
for (var prop in obj) {
// important check that this is objects own property
// not from prototype prop inherited
if(obj.hasOwnProperty(prop)){
alert(prop + " = " + obj[prop]);
}
}
}
Reference: https://stackoverflow.com/a/921808/1054926
groupo[i] is already a text object so you there is an error there. Also, you don't want to look until your index is <= to the length.
Here is a quick look at what you may be looking for in your loop:
for (i=0;i<grupo.length;i++) {
console.log(i,grupo[i].a);
}
However you will have additional problem when you discover that the value of "a" is not what you may be expecting.
Here another possible "solution"
var text = {};
var grupo = [];
text.a = "texta";
text.b = "textb";
grupo.push(text);
text.a = "textc";
grupo.push(text);
for (var i=0;i < grupo.length;i++) {
var x = grupo[i];
if (x && x.a){
console.log(x.a);
} else {
console.log(x);
}
}

Object property in prototype

I have a problem I can't solved because I can't explain this behaviour :
var A = function(value) {
this.prop = value;
};
A.prototype = {
prop: 0
};
var a = new A(1);
var b = new A(2);
console.log(a.prop);
console.log(b.prop);
output :
1
2
But, with this code (almost the same) :
var A = function(value) {
this.prop.value = value;
};
A.prototype = {
prop: {
value: 0
}
};
var a = new A(1);
var b = new A(2);
console.log(a.prop.value);
console.log(b.prop.value);
I have this output :
2
2
Can anybody explain me this ?
Thanks...
EDIT :
Here's a solution :
var A = function(value) {
this.prop = {};
this.prop.value = value;
};
A.prototype = {
};
var a = new A(1);
var b = new A(2);
console.log(a.prop.value);
console.log(b.prop.value);
In example 1, this.prop is a primitive type, which is referenced by value and thus not shared between instances.
In example 2, this.prop is an Object whose reference is initialized from the prototype from a single object, so this single object is shared by all instances.
In the last "example" solution, you create a new object with = {}, so all instances now have their own object.
More details about primitive types : Primitive value vs Reference value
prototype is created only once and it's only a simple object whose childs are attached for all instances of a function it belongs to.
So it's basically the same as if you write:
var obj = { value: 0 };
var a = {}, b = {};
a.obj = obj;
b.obj = obj;
obj.value = 2;
as you can see both a.obj and b.obj references to the same obj and both a.obj.value and b.obj.value will be 2 in this example
This is happening because in JS, objects are passed by reference, while primitives are not.
Since the prototype is shared between the 2 instances, modifying a object on it will update all instances.
Think of a prototype property as a property shared amongst all instances.
Yet you can override it on each instance, that 's what you do in the first example.
Once overriden in each instance, you do not access any more to the prototype property with obj.prop, which now refers to the instance property. You would need to use obj.prototype.prop to read it again, but this syntax is illegal : you can use obj.__proto__.prop (non standard) or Object.getPrototypeOf(obj).prop (EcmaScript 5) to do so.
In the second instance, you do not change the property in the constructor : rather you change a property of this property. So both constructor access to the very same object, then change one of its property value, so the last to set it will 'win'. Here the prototype property is not overriden ('hidden') by the instance property and accessing obj.prop in fact access 'obj.prototype.prop'.

How does this JavaScript-pattern works: Namespaced constructor

I'm having problems to understand how this operation:
tmp.setAttribute(i, prop[i]);
goes through in this for-loop. How prop-array creates 2 arguments. As I understand var = i is just a variable right? But apparently it becomes the 1:st argument in the method just like that?
Thanks for your time.
http://jsbin.com/ozoqob/2/edit
var MYAPP = MYAPP || {};
MYAPP.dom = {};
MYAPP.dom.Element = function(type, prop){
var tmp = document.createElement(type);
for (var i in prop) {
tmp.setAttribute(i, prop[i]);
/*
WHAT I DONT UNDERSTAND IS HOW THIS FOR-LOOP DIVIDE THE ARRAY IN TWO ARGUMENTS?? BEACAUSE 'I' IS JUST A VARIABLE WHICH IS USED TO LOOP THRU THE ARRAY BUT APPARENTLY NOT RIGHT?
*/
console.log(i); // how? is this arguments divided?
console.log(prop[i]);
}
return tmp;
};
var el1 = new MYAPP.dom.Element(
'a',
{href:'http://phpied.com'}
);
console.log(el1);
2 concepts:
every object in JavaScript is a hash table thus you can access its property value by a key e.g. obj[key];
the for-in loop in JavaScript loops keys in the target object (instead of looping values)
In your code, for (var i in prop) loops all the keys in object prop and stores each key in i. So, for each key i, you can get its value by prop[i].
You pass an object as the 2nd argument to the method. You then enumerate the properties of that object with a for...in loop. At every iteration of the loop, i will refer to the identifier of a property of the object, and prop[i] will therefore refer to the value of that property:
var prop = {
prop1: "value1",
prop2: "value2"
};
for (var i in prop) {
console.log(i); // "prop1", "prop2"
console.log(prop[i]); // "value1", "value2"
}
This behaviour is explained in the spec, and is summed up by this line if you imagine P is i in the above example:
Let P be the name of the next property of obj whose [[Enumerable]] attribute is true.

Categories