我仍然认为自己至少是JavaScript的“半菜鸟”。我试图让原型继承下降&我想玩闭包。因此,我决定为货币翻译创建一个概念验证演示。
我显然没有'非常正确'的继承,并需要一些反馈。我相信我需要改变公式...所以我不是在问那个部分。我也承诺在完成后发布完成的版本。
我的问题是:
守则
<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>
答案 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。