2

I have an object that looks like this:

var foo = {
    parent: {
        childOne: {
            prop: 1,
            doSomething: function(){
                return this.prop;
            }
        },
        childTwo: {
            prop: 2,
            doSomething: function(){
                return this.prop;
            }
        }
    },
    other: {
        action: function(){
            return foo.parent.childOne.doSomething() +
                foo.parent.childTwo.doSomething();
        }
    }
}

window.alert(foo.other.action());

Live example.

Here the doSomething() function is definitely duplicate code and I would like to avoid it, this is something similar to what inheritance solves.

I was thinking if there is any way of doing something along the lines of:

parent: {
    doSomething: function(){
        return this.prop;
    }
} 

But not sure how to actually implement it, is this possible?

3
  • Is there a need for the doSomething function, if you can access the properties directly? Commented Apr 25, 2014 at 23:00
  • @KimGysen mainly for organization and some sort of encapsulation. This is also an oversimplified example. Commented Apr 25, 2014 at 23:03
  • Hmm ok, just wondering; because the properties are not private, you could simply do: return foo.parent.childOne.prop + foo.parent.childTwo.prop; and you are rid of the doSomething repetition... Commented Apr 25, 2014 at 23:05

3 Answers 3

1

You would still have to context bind:

function something(context){
  return function(){
    return context.prop;
  }
}

Now:

doSomething: something(this);

Now, just call doSomething() like you do inside your foo.other.action method.

Sign up to request clarification or add additional context in comments.

1 Comment

Yes, that could be a reasonable solution, right now the functions are too short to justify that, if the functions get more complex, it might warrant it.
1

Maybe something like this would allow you to get rid of some duplicated code:

var foo = {
    parent: {
        doSomething: function() {
            return this.prop;
        },
        childOne: {
            prop: 1
        },
        childTwo: {
            prop: 2
        }
    },
    other: {
        action: function() {
            var fooPar = foo.parent;
            return fooPar.doSomething.call(fooPar.childOne) +
                   fooPar.doSomething.call(fooPar.childTwo);
        }
    }
}

Demo: http://jsfiddle.net/YN7G6/5/

1 Comment

this is an interesting possibility, but it's making me doubt if I have the right approach for this. I am basing my code on this suggestion: css-tricks.com/… and it seems to have this disadvantage.
1

If you're only concerned about duplicate code, you can simply factor out the function. Your this already handles binding the proper context.

function bar() {
    return this.prop;
}

var foo = {
    parent: {
        childOne: {
            prop: 1,
            doSomething: bar
        },
        childTwo: {
            prop: 2,
            doSomething: bar
        }
    },
    other: {
        action: function() {
            return foo.parent.childOne.doSomething() +
                   foo.parent.childTwo.doSomething();
        }
    }
}

If you want to do away with the redundant doSomething: bar altogether, you can also use the call method to explicitly bind the context.

var foo = {
    parent: {
        childOne: {
            prop: 1 
        },
        childTwo: {
            prop: 2
        }
    },
    other: {
        action: function(){
            return bar.call(foo.parent.childOne) +
                   bar.call(foo.parent.childTwo);
        }
    }
}

1 Comment

Sure. The magic is all happening in the this, which you already have. A good resource for really understand what this is all about is here: howtonode.org/what-is-this

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.