1

我正在创建一个测验交互,经过几天的研究,我试图确定声明我的对象的最佳方式。有一个主匿名函数(可以称为测验,但不需要公共方法),其中包含场景的类定义,其中包含问题的类定义:

测验 > 情景 > 问题 > 答案(最终)

我更喜欢立即调用('iffy')模型来强制执行私有/公共,但我也需要多个实例,所以我相信我应该使用原型?我已将类定义设为私有,因为它们仅用于此交互。这是最好的模型吗?

JsFiddle:http: //jsfiddle.net/QtCm8/

(function(quizData) {
    var scenarios = [];
    for(var s=0;s<quizData.scenarios.length;s++) scenarios.push(new Scenario(quizData.scenarios[s]));
    function Scenario(scenarioData) {
        console.log("New Scenario: " + scenarioData.title);
        var questions = [];
        for(var q=0;q<scenarioData.questions.length;q++) questions.push(new Question(scenarioData.questions[q]));
        function Question(questionData) {
            console.log("New Question: " + questionData.text);
            // Repeat pattern for future answers object
        }
    }
})({
    scenarios: [
        {
            title: 'Scenario1'
            ,questions: [
                {
                    text: 'What is 1+1?'
                }
                ,{
                    text: 'What is 2+2?'
                }
            ]
        }
    ]
});
4

3 回答 3

0

首先,Javascript 中没有类,只有对象。它是一种基于原型的语言(不是基于类的),它的功能是一流的对象。顺便说一句,aprototype是一个对象,您创建的每个函数都将它指向一个新的空白对象。只有一个使用函数模拟的“类”概念。

这个即时模式(又名匿名函数)对于提供更干净的命名空间非常有用。当有一项工作只需要完成一次时,它也很有用,例如初始化代码,因此没有理由拥有可重用的命名函数。

但是,如果您需要可重用的成员(例如方法),是的,它应该去prototype. 向原型属性添加公共属性和方法,允许这些公共部分在使用相同构造函数创建的所有实例之间共享。

也许您正在寻找Module Pattern,它是诸如

  • 命名空间,
  • 即时功能,
  • 私人会员等
于 2013-02-19T20:05:01.720 回答
0

考虑将你的类打包成对象。以下是我想出的设计模式。由于您有这么多相互依赖的类,我认为最好将它们排列成一个对象。这是代码:

var quiz = {};

quiz.init = (function(data) {
    this.scenarios = this.questions = this.answers = [];

    this.data = {
        Question: data.Question.bind(this),
        Answer: data.Answer.bind(this),
        Scenario: data.Scenario.bind(this)
    };

    this.set_data = function(qas) {
        // fill the arrays here
        // Question, Scenario and Answer are now this.data.Question/Answer...
        // you can use a variable to shorten the names here
    };
});

var Quiz = function(data) {
    return new quiz.init(data);
};

var data = { // classes are defined here
    Question: function() {},
    Answer: function() {},
    Scenario: function() {}
};

var q = Quiz( data );

q.data.set_data(/* Big object literal goes here */);
于 2013-02-18T22:38:48.777 回答
0

就个人而言,我喜欢使用返回他们希望公开的属性的类定义。以下是您的案例的示例。你可以玩弄这个结构并找到你最喜欢的东西,但它应该给你一些例子:

// Namespace
var q = {};

q.Quiz = function Quiz (data) {

    // Private code & variables
    var scenarios = [];
    for (var i = 0; i < data.scenarios.length; i++) {
        scenarios.push(new q.Scenario(data.scenarios[i]));
    }

    // Return public methods & values
    return {
        scenarios: scenarios
    };
};

q.Scenario = function Scenario (sData) {

    // Private inner class
    var Question = function (qData) {
        console.log("New Question: " + qData.text);
        return {
            text: qData.text
        };
    };

    console.log("New Scenario: " + sData.title);
    var questions = [];
    for (var i = 0; i < sData.questions.length; i++) {
        questions.push(new Question(sData.questions[i]));       
    }

    return {
        questions: questions
    };
};

var data = {
    scenarios: [
        {
            title: 'Scenario1'
            ,questions: [
                {
                    text: 'What is 1+1?'
                }
                ,{
                    text: 'What is 2+2?'
                }
            ]
        }
    ]
};

console.log(new q.Quiz(data));

这里的工作示例:http: //jsfiddle.net/5M8bp/

或者,您摆脱 return 语句并使用“this”关键字定义公共属性和方法。例如:

q.Quiz = function Quiz (data) {

    this.scenarios = [];

    for (var i = 0; i < data.scenarios.length; i++) {
        this.scenarios.push(new q.Scenario(data.scenarios[i]));
    }
};

q.Scenario = function Scenario (sData) {

    // Private inner class
    var Question = function (qData) {
        console.log("New Question: " + qData.text);
        this.text = qData.text;
    };

    console.log("New Scenario: " + sData.title);
    this.questions = [];
    for (var i = 0; i < sData.questions.length; i++) {
        this.questions.push(new Question(sData.questions[i]));       
    }
};
于 2013-02-18T22:59:57.547 回答