2011-07-28 39 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

感谢您的输入! –