在JavaScript中创建货币翻译器

时间:2011-07-28 20:42:25

标签: javascript jquery closures

我仍然认为自己至少是JavaScript的“半菜鸟”。我试图让原型继承下降&我想玩闭包。因此,我决定为货币翻译创建一个概念验证演示。

我显然没有'非常正确'的继承,并需要一些反馈。我相信我需要改变公式...所以我不是在问那个部分。我也承诺在完成后发布完成的版本。

我的问题是:

  1. 为什么每个实例都不评估为货币?
  2. 此外,您对一般设计的任何提示也会很棒。
  3. 守则

    <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>
    

2 个答案:

答案 0 :(得分:1)

这是更好的设计,因为你集中分配了实例变量:

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

接下来,定义Currency的原型中子类继承的方法:

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()时,您实际分配的是匿名对象而不是货币。

答案 1 :(得分:0)

首先,如果在为原型分配之前没有定义美元,则代码不会运行,因此您可能更喜欢以下顺序。 接下来,.prototype.constructor应该只是Dollar,而不是new Dollar()。

      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();

好的,至于你的警报,我确实有“美元是货币实例”。 但雷亚不是美元的例子。 Reais是货币的实例(通过其原型),但货币不知道Dollar,因为它的原型直接默认为Object。