javascript - 在 JavaScript 中创建货币转换器

标签 javascript jquery closures

<分区>

我仍然认为自己至少是 JavaScript 的“半菜鸟”。我正在尝试减少原型(prototype)继承并且我想玩闭包。因此,我决定为货币转换器创建一个概念验证演示。

我显然没有“完全正确”的继承,需要一些反馈。我确定我需要更改公式...所以我不是在问那部分。我也保证在完成后发布完成的版本。

我的问题是:

  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>

更新:最终版本:
按照 promise 。感谢您的帮助!

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

最佳答案

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

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

接下来在Currency的原型(prototype)中定义要被子类继承的方法:

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 时使用正确的构造函数
Dollar.prototype = new Currency();
Dollar.prototype.constructor = Dollar;

instanceof 测试现在也会成功。您的代码中的问题是您的 Currency 构造函数返回了一个匿名对象。因此,当将 new Currency() 分配给 Dollar.prototype 时,您实际分配的是匿名对象而不是 Currency。

关于javascript - 在 JavaScript 中创建货币转换器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6865410/

相关文章:

javascript - 拖动以像在 iPhone 中一样使用 jQuery 更改图像幻灯片

rust - 类型不匹配错误 : expected `char` , 找到引用

objective-c - 将 Swift 2 闭包转换为 Objective-C block

javascript - 获取列表项的文本内容

javascript - AngularJS 单页应用程序 : Reference Error, ____ 未定义

javascript - 在强制布局中禁用节点拖动

javascript - jQuery.remove() 真的是同步的吗?

javascript - 向 javascript 函数传递参数失败

javascript - 如何使用 faker.js 生成大写字母

javascript - 左右移动 SVG 组