【问题标题】:Choose which set of methods an object has, based on argument during object creation - JavaScript根据对象创建期间的参数选择对象具有的方法集 - JavaScript
【发布时间】:2012-01-05 02:46:45
【问题描述】:

我已经搜索和阅读了几个小时,但我仍然无法理解创建一个新对象的基本设计模式,该对象可以选择取决于其中一个参数设置的不同方法(同名)。这是一些代码来解释我正在尝试做的事情。 欢迎所有建议和替代方法。我希望有人能把我从这片无知的阴云中解放出来。 谢谢

function BaseConstructor(whichMethods) {
    if (whichMethods==='a') {
         // do something to incorporate methodSetA
    }
    else if (whichMethods==='b') {
        // do something to incorporate methodSetB
    }

    this.init();
};

var methodSetA = {
    init: function() {
        // do initialisation A way
    },
    speak: function() {
        alert('i speak AAA way')
    }
};

var methodSetB = {
    init: function() {
        // do initialisation B way
    },
    speak: function(){
        alert('i got BBB all the way')
    }
};

thing = new BaseConstructor('b'); 
// b is an instance of BaseConstructor and has done the bWay init() function

thing.speak() // return alert 'i got BBB all the way'

【问题讨论】:

    标签: javascript interface new-operator


    【解决方案1】:

    您可以使用工厂函数(为您创建适当对象的常规函数​​)这样做:

    function BaseConstructor(whichMethods) {
        var elem;
        if (whichMethods==='a') {
             elem = new MethodSetA();
        } else if (whichMethods==='b') {
             elem = new MethodSetB();
        } else {
             // figure out what to do here if whichMethods is neither of the previous options
        }
    
        elem.init();
        return(elem);
    };
    

    并将其作为常规函数调用来调用:

    var thing = BaseConstructor('b');
    thing.speak();
    

    注意:new 不能与 BaseConstructor() 一起使用,因为它是常规函数调用。

    【讨论】:

    • 知道了,感谢及时回复!工厂设计模式——我今天一定已经阅读了 5 次,并且有点认为这是我需要的,但总是在无关的细节上分心。再次感谢@jfriend00
    【解决方案2】:

    好吧,要按照自己的方式使用“方法集”,您可以迭代并复制到 this (here's a demo):

    function copy(source, destination) {
        for(var x in source) {
            if(source.hasOwnProperty(x)) {
                destination[x] = source[x];
            }
        }
    }
    
    function BaseConstructor(whichMethods) {
        if(whichMethods === 'a') {
            copy(methodSetA, this);
        } else if(whichMethods === 'b') {
            copy(methodSetB, this);
        }
    
        this.init();
    }
    

    不过,我个人更愿意直接分配给this

    【讨论】:

    • 感谢您的建议并找到“我的方式”的方法,我将从您的代码中学习。再次感谢@minitech
    【解决方案3】:

    您正在寻找工厂模式。 示例:

        function objectFactory(whichMethods) {
            if (whichMethods==='a') {
                return new objectSetA();
            }
            else if (whichMethods==='b') {
                return new objectSetB()
            }
        };
        function objectSetA() {
            this.init = function() {
            // do initialisation A way
            },
            this.speak = function() {
                alert('i speak AAA way')
            }
        };
    
        function objectSetB() {
            this.init = function() {
            // do initialisation B way
            },
            this.speak = function(){
                alert('i got BBB all the way')
            }
        };
        var thing = objectFactory('b'); 
        thing.speak();
    

    【讨论】:

    • 感谢您及时明确的回复,我确实需要工厂! @petar
    • speak 方法应该在各自的构造函数的原型上。
    • @RobG 将 speak() 方法放在原型上是有意义的。你有什么理由不在原型上建议 init() 方法吗?
    • init() 和 speak() 方法最适合原型是的。其实我把所有的变量都放在了函数的构造函数里,把所有的方法都放在了原型里。
    猜你喜欢
    • 2021-10-03
    • 2018-07-25
    • 2019-04-23
    • 2018-12-27
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多