2011-07-28 38 views
2

我仍然認爲自己至少在JavaScript中是一個'半小吃'。我試圖讓原型繼承下來&我想玩關閉。因此,我決定爲貨幣轉換器創建一個概念驗證演示。在JavaScript中創建貨幣翻譯器

我顯然沒有繼承「非常正確」,需要一些反饋。我確定我需要改變這個公式......所以我沒有問這個部分。我也承諾完成後發佈完成的版本。

我的問題是:

  1. 爲什麼不每個實例評估爲貨幣?
  2. 此外,您可能對常規設計的任何提示都會很棒。

守則

<script src="Scripts/jquery-1.4.1.js" type="text/javascript"></script> 
<script type="text/javascript"> 
<!-- 
    function Currency(country, code, imageURL, name) 
    { 
     this.country = country;    //EXAMPLE: America 
     this.code = code;     //EXAMPLE: USD 
     this.imageURL = imageURL;   //EXAMPLE: "http://someplace/mySymbol.gif" 
     this.name = name;     //EXAMPLE: Dollar 
     this.amount = parseFloat("0.00"); //EXAMPLE: 100 
    }; 
    Currency.prototype.convertFrom = function (currency, factor) { 
     this.amount = currency.amount * factor; 
    } 

    function Dollar(country, code, imageURL, name) { 
     Currency.call(this, country, code, imageURL, name); 
    }; 
    Dollar.prototype = new Currency(); 
    Dollar.prototype.constructor = Dollar(); 

    function Reais(country, code, imageURL, name) { 
     Currency.call(this, country, code, imageURL, name); 
    }; 
    Reais.prototype = new Currency(); 
    Reais.prototype.constructor = Reais(); 

    jQuery(document).ready(function() { 

     var dollar = new Dollar('America', 'USD', '', 'Dollar'); 
     var reais = new Reais('Brazil', 'BRL', '', 'Reais'); 

     dollar.amount = 100; 
     reais.amount = 100; 

     // Why isnt this evaluating to true? 
     if (dollar instanceof Currency) 
      alert("dollar is Currency"); 

     // Why isnt this evaluating to true? 
     if (reais instanceof Currency) 
      alert("reais is Currency"); 

     if (dollar instanceof Dollar) 
      alert("this Currency is a Dollar"); 

     if (reais instanceof Reais) 
      alert("this Currency is a Reais"); 

     dollar.convertFrom(reais, 1.2); 
     alert("'" + reais.amount + "' Reais converts into '" + dollar.amount + "' Dollars"); 
    }); 
--> 
</script> 

更新:最後版本:
作爲承諾。謝謝您的幫助!

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="CurrencyTranslator.ascx.cs" Inherits="Concept.CurrencyTranslator.UserControls.CurrencyTranslator" %> 

<style type="text/css"> 
.currency { } 
span.currency { } 
input.currency 
{ 
    text-align: right; 
    width: 70px; 
} 
</style> 

<script type="text/javascript"> 
<!-- 
    // ------------------------ 
    // Currency - Base Class 
    function Currency(country, code, imageURL, name) { 
     this.country = country; 
     this.code = code; 
     this.imageURL = imageURL; 
     this.name = name; 
     this.amount = parseFloat("0.00"); 
    }; 

    // ------------------------ 
    // Pound 
    function Pound(imageURL) { 
     Currency.call(this, "Greate Britain", "GBP", imageURL, "Pound"); 
    }; 
    Pound.prototype = new Currency(); 
    Pound.prototype.constructor = Pound; 

    // ------------------------ 
    // Dollar 
    function Dollar(imageURL) { 
     Currency.call(this, "America", "USD", imageURL, "Dollar"); 
    }; 
    Dollar.prototype = new Currency(); 
    Dollar.prototype.constructor = Dollar; 

    // ------------------------ 
    // Reais 
    function Reais(imageURL) { 
     Currency.call(this, "Brazil", "BRL", imageURL, "Reais"); 
    }; 
    Reais.prototype = new Currency(); 
    Reais.prototype.constructor = Reais; 

    // ------------------------ 
    // CurrencyElement 
    function CurrencyElement(element) { 
     this.element = element; 
    }; 
    CurrencyElement.prototype.update = function (rate) { 

     var element = jQuery(this.element); 
     var float = element.extractValue(); 
     var value = float * rate; 

     if (element.is('input:text')) 
      $(this.element).val(jQuery.formatNumber(value.toString(), { format: "#,###", locale: "us" })); 

     if (element.is('span')) 
      $(this.element).text(jQuery.formatNumber(value.toString(), { format: "#,###", locale: "us" })); 
    }; 

    // ------------------------ 
    // CurrencyTranslator 
    function CurrencyTranslator(currency) { 
     this.current = currency; 
     this.elements = new Array(); 
     this.crossRates = new Array(); 
    }; 
    CurrencyTranslator.prototype.notify = function (crossRate) { 
     for (var i = 0; i < this.elements.length; i++) { 
      this.elements[i].update(crossRate.rate); 
     }; 
    }; 
    CurrencyTranslator.prototype.changeTo = function (currency) { 
     var crossRate = this.findCrossRate(this.current, currency); 
     this.current = currency; 
     this.notify(crossRate); 
    }; 
    CurrencyTranslator.prototype.findCrossRate = function (from, to) { 
     var crossRate = null; 
     for (var i = 0; i < this.crossRates.length; i++) { 
      if ((this.crossRates[i].from.constructor === from.constructor) && (this.crossRates[i].to.constructor === to.constructor)) 
       crossRate = this.crossRates[i]; 
     }; 
     return crossRate; 
    }; 

    // ------------------------ 
    // CurrencyCrossRate 
    function CurrencyCrossRate(from, to, rate) { 
     this.from = from; 
     this.to = to; 
     this.rate = parseFloat(rate); 
    }; 

    // ------------------------ 
    // Controller - Module 
    var currencyTranslator = (function ($) { 
     var publicInstances = {}; 

     publicInstances.controller = controller; 
     function controller(currency, crossRates) { 

      var self = this; 

      this.cssClass = '.currency'; 
      this.dropDownCssClass = '.currency-dropDown'; 

      this.ddlCurrency = $(self.dropDownCssClass); 
      this.hidCurrentCurrency = $("input[id$='hidCurrentCurrency']"); 
      this.hidOriginalCurrency = $('input[id$="hidOriginalCurrency"]'); 

      this.translator = new CurrencyTranslator(currency); 

      this.initialize = function() { 

       $(self.cssClass).each(function() { 
        self.translator.elements.push(new CurrencyElement(this)); 
       }); 

       self.ddlCurrency.change(self.currencyChanged); 
      }; 
      this.currencyChanged = function() { 

       var selected = $('option:selected', self.ddlCurrency); 
       var currency = new window[selected[0].text](null); 

       self.hidCurrentCurrency.val(selected[0].text); 
       self.translator.changeTo(currency); 
      }; 
      this.populateCrossRates = function (json) { 

       $.each(json, function() { 

        var from = new window[this.From.Name](null); 
        var to = new window[this.To.Name](null); 

        self.translator.crossRates.push(new CurrencyCrossRate(from, to, this.Rate)); 
       }); 
      }; 

      self.initialize(); 
      self.populateCrossRates(crossRates); 
     }; 

     return publicInstances; 
    })(jQuery); 
--> 
</script> 

<asp:HiddenField ID="hidCurrentCurrency" runat="server" /> 
<asp:HiddenField ID="hidOriginalCurrency" runat="server" /> 
<label style="display:block; font-weight: bold;">Choose a Currency</label> 
<asp:DropDownList ID="ddlCurrency" runat="server" CssClass="currency-dropDown" Width="100"></asp:DropDownList> 

回答

1

,因爲你做集中分配實例變量這將是更好的設計:

function Currency(country, code, imageURL, name, amount) 
{ 
    this.country = country; 
    this.code = code; 
    this.imageURL = imageURL; 
    this.name = name; 
    this.amount = amount; 
} 

下一個定義是由子類中貨幣的原型繼承的方法:

Currency.prototype.convertFrom = function (currency, factor) { 
    this.amount = currency.amount * factor; 
} 

你可以使用構造函數鏈來節省一些冗餘代碼:

function Dollar(country, code, imageURL, name) { 
    Currency.call(this, country, code, imageURL, name); 
} 

首先將繼承層次,後者確保與new

Dollar.prototype = new Currency(); 
Dollar.prototype.constructor = Dollar; 

創建美元instanceof測試現在也成功當右側構造函數使用。代碼中的問題是您的Currency構造函數返回了一個匿名對象。因此,在爲Dollar.prototype分配new Currency()時,您實際分配的是匿名對象而不是貨幣。

+0

@PERERER ZERO:哎呀,我在Currency.call中忘了'this',對不起。這樣,你的屬性將被正確設置。 – emboss

+0

已更新!這是一個很酷的伎倆。非常感謝您的意見! –

+0

不客氣! – emboss

0

首先,如果您在分配原型之前沒有定義美元,那麼您的代碼將無法運行,因此您可能更願意遵循以下順序。 接下來,.prototype.constructor應該只是美元,而不是新的美元()。

 function Dollar(country, code, imageURL, name) { 
      this.country = country; 
      this.code = code; 
      this.imageURL = imageURL; 
      this.name = name; 
     }; 

     Dollar.prototype = new Currency(); 
     Dollar.prototype.constructor = new Dollar(); 

好吧,至於你的警報我確實有「美元是Instanceof貨幣」。 然而,雷亞爾並不是美元的例子。雷亞爾是貨幣的實例(通過其原型),但貨幣不知道美元,因爲它的原型直接默認導致Object。

+0

更新...任何其他設計技巧?謝謝! –

+0

如果你繼續使用原型繼承:不要在美元和雷亞爾中分配國家代碼等,你應該同時調用Currency.apply(this,[] .slice)。調用(參數));然後在貨幣中指定這些變量,就像您爲美元做的那樣 – user753642

+0

感謝您的輸入! –