我正在创建一个测验互动,经过几天的研究,我正在尝试确定声明我的对象的最佳方式。有一个主匿名函数(可以称为测验,但不需要公共方法),它包含一个包含问题类定义的场景的类定义:
测验>场景>问题>答案(最终)
我更喜欢立即调用('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?'
}
]
}
]
});
答案 0 :(得分: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 */);
答案 1 :(得分: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/
或者,您可以使用'this'关键字删除return语句并定义公共属性和方法。例如:
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]));
}
};
答案 2 :(得分:0)
首先,Javascript中没有类,只是对象。它是prototype-based语言(不是基于类的),其函数是first-class objects。顺便说一句,prototype
是一个对象,你创建的每个函数都会指向一个新的空白对象。只有使用函数模拟“类”的概念。
正如您所说,立即模式(也称为匿名函数)对于提供更清晰的命名空间非常有用。当有一项工作只需要进行一次,例如,它也很有用。初始化代码,因此没有理由拥有可重用的命名函数。
但是,如果您需要可重复使用的成员(例如方法),是的,它应该转到prototype
。向prototype属性添加公共属性和方法,允许在使用相同构造函数创建的所有实例之间共享这些公共部分。
也许您正在寻找 Module Pattern ,这是
等模式的组合