Trufa
Trufa

Reputation: 40717

How to share functions which are object properties and avoid duplicate code

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?

Upvotes: 2

Views: 47

Answers (3)

christang
christang

Reputation: 533

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);
        }
    }
}

Upvotes: 1

dfsq
dfsq

Reputation: 193261

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/

Upvotes: 1

StackSlave
StackSlave

Reputation: 10627

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.

Upvotes: 1

Related Questions