Is it possible for one variable to point to another in an array like this,
var theArray = [0,1,2,3];
var secondElement = //somehow point to theArray[1]
so that if I modify theArray[1], secondElement should also be modified and vice versa (possibly, without using functions)?
There's no way to do that directly. The array could be an array of objects, and you could modify properties of the objects instead of the array entries directly. Then you would have:
var theArray = [ { value: 0 }, { value: 1 }, { value: 2 }, { value: 3 } ];
var secondElement = theArray[1];
then changes to theArray[1].value would also be visible in secondElement.value.
I would offer the observation that functions are friendly things and they won't hurt you if you don't try and pick them up by the tail.
You can use object properties and wrap your array with an object:
var a = {arr: [1,2,3,4]};
var b = a;
b.arr[0] = 777;
console.log(a.arr);
This method has the advantage that you can also assign new values to both a.arr and b.arr.
var a = {arr: [1,2,3,4]};
var b = a;
a.arr = [777,888];
console.log(b.arr);
You're asking about references -- for primitive values, it's not directly possible in Javascript. It is possible w/r/t objects:
C:\WINDOWS>jsdb
js>a = []
js>b = {refToA: a}
[object Object]
js>b.refToA.push(3)
1
js>a
3
js>a.push(4)
2
js>b.refToA
3,4
js>
In the above example, the object b has a property refToA which contains the object a; both reference the same actual object, so changes to the object b.refToA and a are reflected through both ways of accessing it. This reference is broken if you reassign either b.refToA or a. Similarly with arrays:
js>x = {y: 3, toString: function() { return 'y='+this.y; }}
y=3
js>a = [x]
y=3
js>b = [3,x]
3,y=3
js>a[0].y = 22
22
js>b
3,y=22
js>b[1].y = 45
45
js>a
y=45
a[0] and b[1] both have a value that is the same reference to an object.
The effect you're looking for can only be achieved if the shared object is a mutable container, so that your two desired variables have (and always have) the same value, which is a reference to the shared mutable container. You can change values in the container, and they will be seen by both means of access. Primitive values (e.g. numbers and strings) are not mutable containers so they can't be used this way.
Related
I want to have an object that inherits an array property and a method to add elements to the inherited array. However, the inherited method yChange() changes the prototype array and not the inherited array. This question explains why the undesired behavior happens. But can't figure out how to get the desired behavior.
var parent = {
x: 0,
y: [],
xChange: function () {this.x += 1},
yChange: function () {this.y.push(1)}
};
var child = Object.create(parent);
child.xChange();
child.yChange();
console.log(child.x, child.y); // 1 [1]
console.log(parent.x, parent.y); // 0 [1]
Desired:
console.log(child.x, child.y); // 1 [1]
console.log(parent.x, parent.y); // 0 []
However, the inherited method yChange() changes the prototype array and not the inherited array.
There is no difference between the "inherited" array and the "prototype" array. They are one and the same.
You have to give child its own array:
var child = Object.create(parent);
child.y = [];
So, I can't inherit an 'own' array as with the number? The question is how to do it with an inherited array.
Everything that is inherited is not "owned" by the child. Even numbers. The difference is that numbers are not mutable, hence the issue is not apparent.
Look closely what here:
this.x += 1
You are assigning a new value to this.x. This will create child.x, not modify parent.x.
Lets look at
this.y.push(1);
You are not assigning anything here. You are reading this.y, which resolves to parent.y and you are mutating the array object itself.
Is it clearer now why you have to assign a new array to child.y (child.y = [];) ? The assignment is what gives the child its own copy of the data.
The difference between the number and array case is that numbers are immutable and arrays are mutable. The immutability of numbers forces you to create a new number and assign it.
Not so with mutable values. You have to explicitly create a copy of the value if you don't want it to be shared (and that's what child.y = []; is basically doing).
Felix is right about an assignment being necessary to change child.y. In your example, you could check to see if the memory addresses are the same first and then assign a new one for the new instance if they match. Like so:
var parent = {
x: 0,
y: [],
xChange: function () {this.x += 1},
yChange: function () {
if (this.y == Object.getPrototypeOf(this).y)
this.y = new Array()
this.y.push(1)
}
};
var child = Object.create(parent);
child.xChange();
child.yChange();
console.log(child.x, child.y); // 1 [1]
console.log(parent.x, parent.y); // []
a = [1,2,3];
b = [[1,2,3],[4,5,6]];
Why is that in javascript a== b[0] return false?
Thank you
In javascript objects are compared by references.
That said: a references to objects are compared, not the objects' contents.
Thus, One object {} will never be equal to another {} even though their contents are equal.
var a = {},
b = {}; // not equal
Whereas if you create a variable by assigning another reference to it like:
var a = {},
b = a; // equal
then both variables would hold the same reference and would be equal.
I am very new to JS, have been working in C/C++ before,
I need an equivalent of below C structure in JSON
struct tmp_t{
int a;
char c_str[1024];
};
struct tmp2_t{
int a2;
.
.
char c2_str[1024];
};
struct my {
int number;
struct tmp_t tmp[100];
struct tmp2_t tmp2[100][1000];
};
For a json like
var myJSON = {
"number":0,
.
.
};
I need to access it like
myJSON.tmp[0].a = 10;
myJSON.tmp2[0][1].c2_str = "hello world"
any input is highly appreciated
Javascript properties are not typed like they are in C so there is no purely "equivalent" expression in javascript. You don't predeclare typed data structures like your C code has. I given variable or property in javascript can be assigned any value or reference - there is not hard typing. So without variables that can only contain a specific type like C has, there's no pre-declaring of data structure definitions like you have included from C.
Instead, you just declare the properties you want to use on a live object or if you intend to use many of them, you can create a prototype which you can instantiate when needed.
A direct declaration of a live object instance somewhat like your last structure would look like this:
var my = {
number: 10,
tmp: new Array(100),
tmp2: new Array(100)
};
This would declare an object named my that had three properties called number, tmp and tmp2. number initially contained the number 10 and the other two properties contained arrays of length 100 who's values were undefined. I don't know of any compact way to predefine your two dimensional array in javascript without running code in a loop to initialize it.
This data defintion would let you access my.number, my.tmp and so on.
If you want your arrays to contains objects with properties themselves, then you need to populate those arrays with the objects.
var my = {
number: 10,
tmp: [{a: 1, c_str: "foo"}, {a: 2, c_str: "whatever"}],
tmp2: new Array(100)
};
Or, in code, you could add in item to the tmp array with code like this:
var my = {
number: 10,
tmp: [],
tmp2: []
};
my.tmp.push({a: 1, c_str: "foo"});
my.tmp.push({a: 2, c_str: "whatever"});
Or, you could create the object separately and then put it in the array:
var obj = {}; // new empty object
obj.a = 1; // assign property
obj.c_str = "foo"; // assign property
my.tmp.push(obj); // put object into the array
obj = {}; // new empty bject
obj.a = 2;
obj.c_str = "whatever";
my.tmp.push(obj);
Or, you could assign each property individually like this:
my.tmp.push({}); // put empty object into the array
my.tmp[0].a = 1; // assign property to the object
my.tmp[0].c_str = "foo"; // assign property to the object
my.tmp.push({});
my.tmp[1].a = 2;
my.tmp[1].c_str = "whatever";
In either case, you could then access the data like this:
console.log(my.tmp[0].a); // 1
console.log(my.tmp[0].c_str); // "foo"
I have an object that looks like this:
var MyObject = {
prop1 = 12345,
prop2 = "string1",
ListOfOtherObject = an array of another type of object,
ListOfAnotherObject = an array of objects}
Let's say I have two objects: Object1 and Object2. Object2 was initially a deep-copy of Object1 and it was modified through the user's interactions with the UI. I'm looking to get the difference between both objects, especially when it comes to the arrays.
For instance, ListOfOtherObject in Object2 might contain a modified version of some objects as well as new objects.
I'm thinking about looping through each array and then looping through each object within but there might be some more efficient way to do it, especially with jquery. Or may be going with JSON.stringify and compares strings and retuns some sort of string difference. I was wondering if anyone had any suggestions on how to do this.
Thanks.
You need to specify what your comparison needs to do. For example, given:
var o = {name: 'fred'};
var p = {name: 'fred'};
var a = {o:o};
var b = {o:o};
then:
a == b; // false, a and b are different objects
a.o == b.o; // true since a.o and b.o reference the same object
but if comparing objects:
b.o = p;
a.o == b.o; // false since a.o and b.o reference different objects
or if comparing primitives:
a.o.name == b.o.name; // true since the value of both expressions is the string 'fred'
// even though a.o and b.o are different objects
Does Type or constructor matter? What about:
b.o = [];
b.o.name = 'fred';
a.o.name == b.o.name; // true or false? a.o is an object, b.o is an array
Does Javascript have associative arrays? Please explain.
Nope; JavaScript arrays are just numeric keys and mixed values. The same thing can be achieved (or, actually, it's exactly the same as associative arrays in other languages) with objects:
var foo = {
a: 123,
b: 'CDE'
};
foo.a; // 123
foo['a']; // 123
You could use arrays:
var foo = [];
foo.a = 123;
foo.b = 'CDE';
foo.b; // CDE
foo['b']; // CDE
HOWEVER, this should never be done because this will not enter the key/value pairs into the array, but add them to the array object as properties. (besides, {a: 123} is easier than a = []; a.a = 123) If you need key/value pairs, use Objects. If you need an enumerated list, use arrays.
This answer is pretty much a copy-paste of my previous answer on this question.
The situation has changed in the five years since this question was asked.
Due to weak typing associative arrays can be faked in JavaScript:
>> var names = new Array();
undefined
>> names["first"] = "Dotan";
"Dotan"
>> names["last"] = "Cohen";
"Cohen"
>> for ( key in names ) { console.log(key+" "+names[key]) }
undefined
first Dotan
last Cohen
That is sometimes useful, and all browsers released since 2012 support it, but there are caveats! The array cannot be simply read back:
>> names
Array [ ]
More importantly, the array's length cannot be easily retrieved:
>> names.length
0
Therefore this is not an associative array in the sense that JavaScript would have supported it had it been intended, but rather a workaround that is often useful if for whatever reason a real JS object does not support what you need:
>> var names = {};
undefined
>> names.first = "Dotan";
"Dotan"
>> names.last = "Cohen";
"Cohen"
>> for ( key in names ) { console.log(key+" "+names[key]) }
undefined
first Dotan
last Cohen
>> names
Object { first: "Dotan", last: "Cohen" }
>> Object.keys(names).length
2
The closest we have is an object; the easiest way you can define this is using object literal syntax.
var assocArray = {
key: 1,
key2: 2
};
You should be wary of a few things however:
It does not have a .length property.
You should use for in to iterative over it, rather than for(;;;);, but should combine it with hasOwnProperty():
for (var x in assocArray) {
if (assocArray.hasOwnProperty(x)) {
// x = the key, assocArray[x] = the value
}
}
There is no concept of ordering/ sorting the members. Whilst all implementations I know of iterate the members in the order they were added, this is not standardised.
Instead of associative arrays. Javascript has objects. Properties of an object are addressed using a string.
var obj1 = {}; // declare empty object
var obj2 = {a: 1, b: 'string', c: [4,5]}; // obj with 3 properties, a, b, and c
// note that the 'c' property contains an anonymous array
alert(obj2.a); // shows 1
obj2.a = 'another string'; // redefine the 'a' property
obj2.cookie = 'oatmeal'; // add a new property to the object
obj2['ice_cream'] = {vendor: 'Beyers',
flavor: 'Chocolate Surprise'}; // add anonymous object as
// a new property for the object
assert(obj2.a === obj2['a']); // two ways to retrieve the value
var i = 'a'; // using an index varable
assert(obj2.a === obj2[i]); // note the i does not have apostrophes around it
See the Quirksmode docs
Something comparable in JavaScript is an object.
var my_obj = { key : 'value' }
Sure it does (kind of, use objects)
var foo = {
bar: "hello"
}
accessible with
foo.bar