Reputation: 3222
Problem: I am really new to object oriented programming. Have been done a lot of reading lately about objects and I am honestly confused about how to access properties of a sub object from within the main object.
If that is not clear I will shown you what I mean:
JSFiddle: http://jsfiddle.net/rn3btqp0/3/
Example:
// Pseudo code
obj1 = {
xy: {
x: 'foo',
y: this.x + 'bar'
}
}
// Working
obj2 = {
xy: (function() {
x = 'foo',
y = console.log(this.x + 'bar')
})()
}
// need to access stuff like this
obj1 = {
xy: {
x: 'foo',
y: this.x + 'bar'
}
z: xy.y
}
Question: As you can see, Im utterly confused with the proceedings of what I believe is called inheritance (correct me im mistaken). What exactly is a valid way of freely accessing properties of objects within an object?
If anything in my question seems unclear or not well structured, please do let me know so that I can make appropriate adjustments.
Upvotes: 2
Views: 89
Reputation:
First, none of this is inheritance. This is more rightly called "composition", where one object is composed of other nested objects.
Looking at your code...
Example 1
// Pseudo code
obj1 = {
xy: {
x: 'foo',
y: this.x + 'bar'
}
}
This example is what people usually want to do, but you simply can't. Using object literal initializers, there's simply no way to refer to the object being created; you need to wait until after it's created. Specifically, this
has no meaning that will pertain to the object being created.
You need to do this:
// Pseudo code
obj1 = {
xy: {
x: 'foo'
}
}
obj1.xy.y = obj1.xy.x + 'bar'
You could give y
some default value if you wish, but none that relies on accessing obj1
or obj1.xy
.
Example 2
// Working
obj2 = {
xy: (function() {
x = 'foo',
y = console.log(this.x + 'bar')
})()
}
With this one, it doesn't actually work. The x =
and and y =
are creating global variables. There's nothing being added to obj2.xy
; it is undefined
.
Example 3
// need to access stuff like this
obj1 = {
xy: {
x: 'foo',
y: this.x + 'bar'
}
z: xy.y
}
Just like Example 1, this can't be done. The this.x + 'bar'
has been explained above, but the z: xy.y
won't work even if y
did have a useful value. This is because obj.xy
doesn't yet exist. There's simply no implicit way to access objects being created while they're being created.
This works but usually not best
There are some tricks that can be done, like using anonymous constructors, but the syntax gets a good bit more verbose.
I'll show it here, but I don't think this is often the best way.
var obj1 = new function() {
this.xy = new function() {
this.x = 'foo',
this.y = this.x + 'bar'
}
this.z = this.xy.y
}
Now any object being created is actually using a temporary anonymous function as a constructor. This is because both functions are invoked using new
. As such, the value of this
in the functions will be the object being created, so we can refer to it. The functions implicitly return the new object, since that's how JS works when invoking a function using new
.
Traditional approach
You're really better of just creating the objects individually. It's a little more verbose, but much clearer.
var obj1 = {
xy: {
x: 'foo'
}
}
obj1.xy.y = obj1.xy.x + 'bar'
obj1.z = obj1.xy.y
Using named constructors
If you like the previous one with the functions, then make actual constructor functions and invoke them.
function MyObj() {
this.x = 'foo'
this.y = this.x + 'bar'
}
function MyOuterObj() {
this.xy = new MyObj()
this.z = this.xy.y
}
var obj1 = new MyOuterObj()
Upvotes: 1