如何共享作为对象属性的函数并避免重复代码

时间:2014-04-25 22:38:01

标签: javascript jquery oop module prototypal-inheritance

我有一个看起来像这样的对象:

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.

这里doSomething()函数肯定是重复的代码,我想避免它,这与继承解决的类似。

我在想是否有任何办法可以按照以下方式行事:

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

但不确定如何实际实现它,这可能吗?

3 个答案:

答案 0 :(得分:1)

你仍然需要上下文绑定:

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

现在:

doSomething: something(this);

现在,只需像doSomething()方法中那样拨打foo.other.action

答案 1 :(得分:1)

也许这样的东西可以让你摆脱一些重复的代码:

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

演示:http://jsfiddle.net/YN7G6/5/

答案 2 :(得分:1)

如果您只关心重复代码,则可以简单地分解出该功能。您的this已经处理了绑定正确的上下文。

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

如果你想完全取消冗余doSomething: bar,你也可以使用call方法显式绑定上下文。

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