2013-02-18 17 views
1

我創建了一個測驗交互,經過幾天的研究,我試圖確定聲明我的對象的最佳方式。有一個主匿名函數(可以稱爲測驗,但沒有公共方法的要求),其中包含針對問題的類定義的類定義:在JavaScript中封裝類清除器的類名定義名稱空間

測驗>方案>問題>答案(最終)我更喜歡Immediately-Invoked('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

考慮包裝你的類爲對象。以下是我提出的設計模式。既然你有很多相互依賴的類,我認爲最好將它們排成一個對象。下面是代碼:

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 */); 
+0

有趣的方法。當它們被設置爲全局變量時,爲什麼要傳入「數據」(類定義)?如果從'(function(data){')中取出參數'data',那麼綁定只會引用全局對象而不是本地對象,是的? – scader 2013-02-19 17:34:29

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]));  
    } 
}; 
+0

感謝您的回覆 - 爲什麼您將Questions作爲內部類,而把Scenario作爲一個根類呢?總的來說,這就是我想要弄清楚的 - 如果它們應該是根或內部定義的話。我應該使用原型定義,以便Scenario和Question類的方法被重用所有的實例? – scader 2013-02-19 14:30:53

+0

備註:最終,我將使用公共方法更新所有類(可能通過返回對象字面值),這樣我就不必返回整個數據對象 – scader 2013-02-19 14:32:22

+0

沒有完美的設計,所以您必須你想在多個不同的場景中使用相同的問題,或者在多種不同的測試中使用相同的問題?如果是這樣,那麼他們應該是公共類,如果不是,那麼m aybe內部類是有道理的。我的例子是演示多種不同的範例。 – Kris 2013-02-19 22:38:21

0

首先,Javascript中沒有類,只是對象。它是一種prototype-based語言(不是基於類),其功能是first-class objects。順便說一句,prototype是一個對象,並且您創建的每個函數都會將它指向一個新的空白對象。只有使用函數模擬的「類」的概念。

This immediate pattern(又名匿名函數)對於提供更清晰的命名空間非常有用,正如您所說的。當只有一項工作需要完成時,它也很有用,例如,初始化代碼,所以沒有理由有一個可重用的命名函數。

但是,如果您需要可重複使用的成員(例如方法),那麼應該轉到prototype。將常用屬性和方法添加到原型屬性中,允許在使用相同構造函數創建的所有實例之間共享這些通用部分。

也許你正在尋找的Module Pattern,這就好比

  • 命名空間patters的組合,
  • 即時功能,
  • 私有成員等
+0

是的,這就是爲什麼我說,「確定宣佈我的對象的最佳方式。」 ;)總的來說,我更喜歡Module模式,但它不包含可重用成員。我正在尋找兩者的完美結合。 – scader 2013-02-19 20:33:17

相關問題