In short, when you have objects nested inside of others, there is no such a thing as a "parent" object in Javascript. The language won't help you get a reference to the parent. You will have to either reference the top level object by name directly yourself or manually put a reference to the top level object in the lower level object as a property.
When I define your object and assign it to a variable data
and run your code and look at the values of data.test0
and data.gradients.test1
and value of this
inside of the data.gradients.g1()
function, they all have exactly the same value for me which is the lexical value of this
in the scope where the object was defined. That's how it should work. this
refers to the lexical scope where the objects were declared, it does not refer to the object itself. Inside a non-fat arrow method (method declared with a regular function), this
will be determined by how the method was called.
Some people get confused on this because when you call a regular method (not defined with a fat-arrow), the value of this
inside that method will often be the object that the method is part of. This is because of how that value of this
is set when a method is called. You can see the six ways the value of this
is set in a regular method call in this answer: The six ways the value of this is controlled or determined.
There is no mechanism in the Javascript language to reference a "parent" object automatically. Objects in Javascript are not actually "contained" within one another. When you do a nested definition like this, the inner objects are created on their own and garbage collected on their own and the outer object just contains a reference to them. It's quite possible that other variables elsewhere in your program can contain the same reference to those nested objects, included inside other object's properties. So, there is no actual "parent" object in Javascript.
So, let's look at some runnable code, related to what you posted:
this.greeting = "hello";
let data = {
cyan400: "#a6fcff",
cyan200: "#d9feff",
test0: this,
gradients: {
test1: this,
g1: (angle = "0deg") => {
console.log(this);
}
}
}
console.log(data.test0);
console.log(data.gradients.test1);
data.gradients.g1();
When I run this in node.js these last three statements all show the exact same output:
{ greeting: "hello" }
Because all three values of this
are the same, which is as expected.
If I then, add a regular method to the gradients
object and call it:
this.greeting = "hello";
let data = {
cyan400: "#a6fcff",
cyan200: "#d9feff",
test0: this,
gradients: {
test1: this,
g1: (angle = "0deg") => {
console.log(this);
},
g2: function() {
console.log(this);
}
}
}
data.gradients.g2();
Then, the value of this
in g2 will be the gradients object. That's because it was called with obj.method()
syntax and it was declared as a regular function (not a fat-arrow function) so the value of this
for obj.method()
is set to obj
which in this case is the gradients
object.
If you're trying to reference properties in a parent object, there is no automatic way to reference that in Javascript using this
or any other mechanism. You will have to either place a reference to the top level object inside of gradients
like this:
let data = {
cyan400: "#a6fcff",
cyan200: "#d9feff",
test0: this,
gradients: {
test1: this,
g1: (angle = "0deg") => {
// use property manually set on this object
// to get to the object that has the colors
console.log(this.colors.cyan400);
}
}
}
// set reference to parent object that contains the colors
// can't be done inside the static declaration, has to be done afterwards
data.gradients.colors = data;
Or, reference the top level name of the object itself and get to the colors that way:
let data = {
cyan400: "#a6fcff",
cyan200: "#d9feff",
test0: this,
gradients: {
test1: this,
g1: (angle = "0deg") => {
// reference top level object directly
console.log(data.cyan400);
}
}
}