So I have an array called xyz containing keys a and b.
I want to input these into another array as follows :
seats =[{
name : xyz.a.
address: xyz.b}];
however the xyz.a is being stored as an object and not by it's value in seats.name and prints undefined when i use console.log
I want to store xyz.a by its value such that seats.name gives the value stored in xyz.a
Javascript doesn't have variable references or aliases. When you assign a variable to another variable or object, it gets its value at the time of the assignment, it doesn't keep a link to the original location.
If you want something that always gets the current value of a variable, you have to use a function:
seats = [ {
name: function() { return xyz.a; },
address: function() { return xyz.b; }
}];
Then you would call the function to get what you want:
seats[0].name();
Assuming xyz is an object like
var xyz = {
a: 'foo',
b: 'bar'
};
Then, you can use
var seats = {
name: xyz.a,
address: xyz.b
};
Related
I'm sure there is a simple way to do this, but am stumped for now.
I have many variables defined at the top of my script (here is an example of two):
var firstVar,secondVar;
Then I have an object which contains those variables:
var myObj = { a: {name:firstVar, number:1}, b: {name:secondVar, number:2}
I want to assign values to those variables:
keys = Object.keys(myObj);
function getAll(e){
var myArray = [];
for (var prop in myObj){
myArray.push(myObj.prop[e]);
}
return myArray;
}
The behaviour I want is:
var nameVars = getAll(name);
// [firstVar,secondVar]
But instead it returns:
// [undefined,undefined]
How else can I get the variables before defining them?
Then I have an object which contains those variables:
No, it doesn't. It contains a copy of the value those variables contained as of when you created the object (which is undefined, since you've never assigned a value to them). Once created, there is no ongoing link between the object property you've copied the value to and the variable.
Since the object has no enduring link to the variables, there's no way for getAll to return the information you've said you want.
You've said in a comment that you're building d3 graphs and have the same structure with some variables, and want to avoid repeating yourself. It sounds to me like you want a builder function:
function buildObject(firstVar, secondVar) {
return { a: {name:firstVar, number:1}, b: {name:secondVar, number:2} };
}
...which you would then use like this:
var obj1 = buildObject("value1", "value2");
// do a graph
var obj2 = buildObject("valueA", "valueB");
// do a graph
...or possibly even something that just takes the variables and produces the graph:
function makeGraph(firstVar, secondVar) {
buildTheGraph({ a: {name:firstVar, number:1}, b: {name:secondVar, number:2} });
}
I don't think it is, but if it's the names you want, just put them in quotes (and also myArray.push(myObj.prop[e]); should be myArray.push(myObj[prop][e]); and getAll(name) should be getAll("name")), but again there's no link to the variables at all:
// Since they're not used, we don't even need these: var firstVar, secondVar;
var myObj = { a: { name: "firstVar", number: 1 }, b: { name: "secondVar", number: 2 } };
function getAll(e) {
var myArray = [];
for (var prop in myObj) {
myArray.push(myObj[prop][e]);
}
return myArray;
}
var nameVars = getAll("name");
console.log(nameVars);
...but note that having the names doesn't help you get the variable values later (unless you use eval, which you should seek to avoid).
I'm looking for a JavaScript function which receives in parameter the field of the object we'd like to have and returns its value :
var object = {
field1 : "test1",
field2 : [
"test2", "test3"
]
};
var getField = function (field){
return object[field];
}
getField("field1"); // working
getField("field2[0]"); // not working due to the array
Am I obliged to split the parameter by "[" to get the correct field ?
To get the correct array item you need to use:
getField("field2")[0] // prints "test2"
When using getField("field2[0]"), you're accessing from object a property with the name "field2[0]", which doesn't exist and will return undefined.
Check more details about the property accessors.
Lets say I have the following object:
name = {
name_one : {
name_one_A : {
name_one_A_a : 'John',
name_one_A_b : 'Kate'
}
}
};
I could create a reference to 'John' by doing:
current_name = name.name_one.name_one_A.name_one_A_a;
Lets say I'm referencing "name.name_one.name_one_A" several times, is there a way to create a referencing to this nesting? This doesn't work, but something like:
A = name.name_one.name_one_A;
name = A.name_one_A_b;
'name' would then equal 'Kate'. I know this doesn't work like that, but I'm just wondering if there is a way to accomplish this?
Thanks for any help!
It's a bit hard to tell exactly what you're asking which has caused some confusion among the answers.
If you're referencing name.name_one.name_one_A multiple times, you can save that once and then use it:
var x = name.name_one.name_one_A;
x.name_one_A_a = 'Bill';
x.name_one_A_b = 'Sue';
This works ONLY because the value of name.name_one.name_one_A is an object (Object, Array or Function). So, when you save it to another variable, you aren't actually saving a reference to name.name_one.name_one_A, but rather getting the value of that property which is itself an object. And, when you then modify that object, since name.name_one.name_one_A also points to that same object, you will see the value change there too.
Javascript does not have the ability to create a reference to a particular property on an object such that you could use only that reference to then change the value of that property.
Using C/C++ terminology, you can't create a pointer to a property on an object in Javascript such that you could change the value in that property using only that pointer.
You would instead have to pass the host object and the property name and you could then change the value of the property on that host object.
Or, if the value of the property was itself an object (Object, Array or Function), then you can get the value of the property and then change the object that it points to.
So, in your data structure:
var name = {
name_one : {
name_one_A : {
name_one_A_a : 'John',
name_one_A_b : 'Kate'
}
}
};
There's no way to get a direct reference to:
name.name_one.name_one_A.name_one_A_a
that would let you modify just the contents of that property at some later time. Instead, you'd have do something like this where you get a reference to the containing object and use that:
var obj = name.name_one.name_one_A;
var prop = "name_one_A_a";
// and then some time later:
obj[prop] = 'Bob';
// or
obj.name_one_A_a = 'Bob';
Firefox Scratchpad had an issue with a variable named "name", but this works:
var foo = {
'name_one' : {
'name_one_A' : {
'name_one_A_a' : 'John',
'name_one_A_b' : 'Kate'
}
}
};
var A = foo.name_one.name_one_A;
console.log(A.name_one_A_b);
//yields
Kate
Update:
You can get a reference that is able to change a property value:
var foo = {
'name_one' : {
'name_one_A' : {
'name_one_A_a' : 'John',
'name_one_A_b' : 'Kate'
}
}
};
var A = foo.name_one.name_one_A;
console.log(A.name_one_A_b);
A.name_one_A_b = "bob";
console.log(A.name_one_A_b);
console.log(JSON.stringify(foo));
Yields:
"Kate"
"bob"
"{"name_one":{"name_one_A":{"name_one_A_a":"John","name_one_A_b":"bob"}}}"
If I have this object:
var myclass = {
foo: {
bar: function(var) {}
},
some: {
bar: function(var) {}
}
}
and I want to call the bar function depending on a variable that defines the parent level of the object like this:
var part = "some";
myclass.part.bar(var);
How can I do?
You can do it using array access notation:
myclass[part].bar(var);
JavaScript objects are like associative arrays, and you can use a property name to either set or get the property's value, you can even create new properties with this syntax.
For example:
var obj = { a : 1 };
console.log(obj["a"]); // 1
obj["b"] = 2; // this creates a property called b and assigns 2 as the value
console.log(obj["b"]); // 2
You can keep a reference to a function as a variable, which is a little cleaner than a string.
var func = myclass.foo.bar;//or myclass.some.bar
...
func.call(myclass, var);
Or keep a reference to the part:
var part = myclass.foo;//or myclass.some
part.bar.call(myclass, var);
i have a object, which is getting passed in many different functions inside a function. these functions may or may not change the value of the object, but if they do change it, then i would like to get the latest changes on object.
following is what im trying to do:
var ob = {text: 'this is me', name: 'john'}
function (object) {
changeObject(object);
customObjectChanger(object);
callback = function (object) {
object.text = 'new text';
}
callback(object);
// object value here should be object{text: 'new text', name: 'john'};
}
In JavaScript objects are always passed by copy-reference. I'm not sure if that's the exactly correct terminology, but a copy of the reference to the object will be passed in.
This means that any changes made to the object will be visible to you after the function is done executing.
Code:
var obj = {
a: "hello"
};
function modify(o) {
o.a += " world";
}
modify(obj);
console.log(obj.a); //prints "hello world"
Having said that, since it's only a copy of the reference that's passed in, if you re-assign the object inside of your function, this will not be visible outside of the function since it was only a copy of the reference you changed.
Code:
var obj = {
a: "hello"
};
function modify(o) {
o = {
a: "hello world"
};
}
modify(obj);
console.log(obj.a); //prints just "hello"
"Objects" are not values in JavaScript, and cannot be "passed".
All the values that you are dealing with are references (pointers to objects).
Passing or assigning a reference gives another reference that points to the same object. Of course you can modify the same object through that other reference.
This is more explanation for Pass by value and Pass by reference (Javascript).
In this concept, they are talking about passing the variable by reference and passing the variable by reference.
Pass by value (Primitive Type)
var a = 3;
var b = a;
console.log(a); // a = 3
console.log(b); // b = 3
a=4;
console.log(a); // a = 4
console.log(b); // b = 3
applies to all primitive type in JS(string, number, boolean, undefined, null).
a is allocated a memory (say 0x001) and b creates a copy of the value in memory (say 0x002).
So changing the value of a variable doesn't affect the other, as they both resides in two different locations.
Pass by reference (objects)
var c = { "name" : "john" };
var d = c;
console.log(c); // { "name" : "john" }
console.log(d); // { "name" : "john" }
c.name = "doe";
console.log(c); // { "name" : "doe" }
console.log(d); // { "name" : "doe" }
JS engine assigns the object to the variable c, it points to some memory say (0x012)
when d=c, in this step d points to the same location (0x012).
changing the value of any changes value for both the variable.
functions are objects
Special case, Pass by reference (objects)
c = {"name" : "jane"};
console.log(c); // { "name" : "jane" }
console.log(d); // { "name" : "doe" }
The equal(=) operator sets up new memory space or address
Basically, In JavaScript, there is no concept of Pass-By-Reference because Pass-by-value serves the purpose which makes JS so special. when we pass an object in JavaScript,
1)function needs to with the value and that value is the reference copy
2)This value to the address of the original object.
How can I handle this problem? What if I want to change the object itself rather than its copy reference?
I wanted to reassign an object within a function and its new value be visible in the calling function.
To add to the great accepted answer, and address unanswered questions in comments there, here's my take on passing by reference with a look at scope / closure in practice:
const obj = {
count: 0,
}
function incrementReference(_obj) {
obj.count++
}
function createIncrementByCopy(_obj) {
let inner = {}
Object.assign(inner, _obj)
return function increment() {
inner.count++
}
}
function createScopedIncrement(_obj) {
return function increment() {
_obj.count++
}
}
function createExtend(_obj) {
return function increment(ext) {
Object.assign(_obj, ext)
}
}
console.log('obj', obj) // { count: 0 }
incrementReference(obj)
console.log('incrementReference ✅', obj.count) // 1
const incrementCopy = createIncrementByCopy(obj)
incrementCopy()
console.log('incrementCopy ❌', obj.count) // 1
const incrementA = createScopedIncrement(obj)
incrementA()
console.log('incrementA ✅', obj.count) // 2
const extendObj = createExtend(obj)
extendObj({ text: 'New Property!' })
console.log('extendObj ✅', obj) // { count: 2, text: 'New Property!' }
The following article discusses a common confusion about the terminology, which I really can't speak to 😆 https://dev.to/bytebodger/a-gotcha-of-javascript-s-pass-by-reference-1afm
Related (good context, more complex, different use case): https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#copying_accessors