I want to compare the classes of 2 JavaScript objects. The current call below fails. The idea here is to deal extract the correct cross-rate using the passed-in "from and to" variables.
Thanks for the help!
UPDATED: The Working Code Now Looks Like This:
<script type="text/javascript">
<!--
// ------------------------
// CLASS
function Currency(clientId, country, code, imageURL, name) {
this.clientId = clientId //EXAMPLE: txtBudget
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;
}
// CLASS
function Pound(clientId, imageURL) {
Currency.call(this, clientId, "Greate Britain", "GBP", imageURL, "Pound");
};
Pound.prototype = new Currency();
Pound.prototype.constructor = Pound;
// CLASS
function Dollar(clientId, imageURL) {
Currency.call(this, clientId, "America", "USD", imageURL, "Dollar");
};
Dollar.prototype = new Currency();
Dollar.prototype.constructor = Dollar;
// CLASS
function Reais(clientId, imageURL) {
Currency.call(this, clientId, "Brazil", "BRL", imageURL, "Reais");
};
Reais.prototype = new Currency();
Reais.prototype.constructor = Reais;
// ------------------------
// CLASS
function Suscriber(element) {
this.element = element;
};
// CLASS
function Publisher() {
this.subscribers = new Array();
this.currencyCrossRates = new Array();
};
Publisher.prototype.findCrossRate = function (from, to) {
var crossRate = null;
for (var i = 0; i < this.currencyCrossRates.length; i++) {
if ((this.currencyCrossRates[i].from.constructor === from.constructor) && (this.currencyCrossRates[i].to.constructor === to.constructor))
crossRate = this.currencyCrossRates[i];
}
return crossRate;
}
// ------------------------
// CLASS
function CurrencyCrossRate(from, to, rate) {
this.from = from;
this.to = to;
this.rate = parseFloat(rate);
};
jQuery(document).ready(function () {
var dollar = new Dollar(null, null);
var reais = new Reais(null, null);
var dollarToReais = new CurrencyCrossRate(dollar, reais, 0.8);
var reaisToDollar = new CurrencyCrossRate(reais, dollar, 1.2);
publisher = new Publisher();
publisher.currencyCrossRates.push(dollarToReais);
publisher.currencyCrossRates.push(reaisToDollar);
// SETUP
jQuery(".currency").each(function () {
publisher.subscribers.push(new Suscriber(this));
});
var newDollar = new Dollar(null, null);
var newReais = new Reais(null, null);
// This now resolves correctly
var first = crossRate = publisher.findCrossRate(newDollar, newReais);
var second = crossRate = publisher.findCrossRate(newReais, newDollar);
});
-->
</script>
The right hand side operator of instanceof should not be the prototype object, but instead the object's constructor function, accessible through the constructor property of the object in question. Since this property in fact references the function which was used to construct the object, comparison is done with the usual equality operator:
this.currencyCrossRates[i].from.constructor == from.constructor
EDIT:
Remove the lines Pound.prototype.constructor = Pound(); etc (one for each currency). The constructor property is a built-in feature which automatically references the correct function. However, it is unfortunately writable and so can be reassigned - don't do it!
The conditions should be of the form this.currencyCrossRates[i].from instanceof from.constructor - the left operand is the Object and the right one is the constructor function.
Related
My constructor Mash needs to have a property that is an array of Grain objects. This is as far as I got and now I am getting an error with my push. Any thoughts?
function Grain(maxPPG, quantity) {
this.maxPPG = maxPPG;
this.quantity = quantity;
this.calMaxPPG = function() {
return this.maxPPG * this.quantity;
};
}
let grain1 = new Grain("Pale Malt (2 Row)", 9, 37);
let grain2 = new Grain("Caramel/Crystal Malt - 20L", .75, 35);
function Mash(volume) {
this.volume = volume;
this.addGrain = function(grain) {
this.grains.push(grain);
}
this.calcEOG = function() {
let total = 0;
this.grains.forEach(item => {
total += item.calMaxPPG();
});
return total / this.volume;
};
}
let mash = new Mash(7);
mash.addGrain(grain1);
mash.addGrain(grain2);
console.log(mash.calcEOG());
You forgot to initialize the variable grains in Mash constructor.
function Mash(volume) {
this.grains = [];
this.volume = volume;
this.addGrain = function(grain) {
this.grains.push(grain);
}
this.calcEOG = function() {
let total = 0;
this.grains.forEach(item => {
total += item.calMaxPPG();
});
return total / this.volume;
};
}
EDIT
Also, your Grain class instances doesn't accept string on it's constructor. I don't know why you're instancing with a name (I guess).
function Grain(name, maxPPG, quantity) {
this.name = name;
this.maxPPG = maxPPG;
this.quantity = quantity;
this.calMaxPPG = function() {
return this.maxPPG * this.quantity;
};
}
Now your instances would work.
EDIT 2: just working on your script :)
Look for those advices:
// before dealing with data, work on your classes
function Grain(name, maxPPG, quantity) {
this.name = name;
this.maxPPG = maxPPG;
this.quantity = quantity;
}
// and as #HMR said, always declare your class functions with prototypes
Grain.prototype.MaxPPG = function() {
return this.maxPPG * this.quantity;
};
function Mash(volume, grains) {
this.volume = volume;
this.grains = grains;
}
Mash.prototype.calcEOG = function() {
var total = 0;
this.grains.forEach(item => {
total += item.MaxPPG();
});
return total / this.volume;
};
// So after all you'll instance your classes easy.
var grain1 = new Grain("Pale Malt (2 Row)", 9, 37),
grain2 = new Grain("Caramel/Crystal Malt - 20L", .75, 35);
var mash = new Mash(7, [grain1, grain2]); // note that litle change I did :p
console.log(mash.calcEOG());
you haven't declared array to push in
You have several errors, constructor is called with 3 parameters but you define it with only 2. You did not initialize the grans array.
One tip: behavior can go on the prototype.
The corrected code will look like this:
function Grain(name,maxPPG, quantity) {//constructor takes 3 parameters when you call it
this.name = name;//assume the first one is name
this.maxPPG = maxPPG;
this.quantity = quantity;
}
//you an add behavior on the prototype:
Grain.prototype.calMaxPPG = function() {
return this.maxPPG * this.quantity;
};
let grain1 = new Grain("Name of grain", 9, 37);
let grain2 = new Grain("Name of grain", .75, 35);
function Mash(volume) {
this.volume = volume;
this.grains=[];//you did not initialize grains
}
//again; add behavior on the prototype
Mash.prototype.addGrain = function(grain) {
this.grains.push(grain);
};
Mash.prototype.calcEOG = function() {
//using reduce instead to sum up all grains
return this.grains.reduce(
function(all,item){
return all + item.calMaxPPG();
},
0
)/this.volume;
};
let mash = new Mash(7);
mash.addGrain(grain1);
mash.addGrain(grain2);
console.log(mash.calcEOG());
I'm having trying to create two objects of type person using factory and on the first try I create the first element and the second attempt instead of creating the second element creates a new element but with the same characteristics as the first element
class Person
function Person(id, name) {
this.id = id;
this.name = name;
}
class Student extends Person
function Student(id, name) {
Person.call(this, id, name);
}
class Teacher extends Person
function Teacher(id, name) {
Person.call(this, id, name);
}
using function factory to create student and teacher
function Factory() {
this.createPerson = function(type, name) {
var person;
var idStudent = 0;
var idTeacher = 0;
switch (type) {
case "1":
person = new Student(idStudent++, name);
break;
case "2":
person = new Teacher(idTeacher++, name);
break;
}
return person;
}
}
class School has an array of person
function School(id) {
this.persons = [];
this.factory = new Factory();
this.personCreate = null;
this.createStudentAndTeacher = function() {
var type = prompt("Choose ? \n\n[1-Student | 2-Teacher ]");
var name = prompt("Write name?");
if (type !== null) {
this.personCreate = this.factory.createPerson(type,name);
this.persons.push(this.personCreate);
} else {
alert("need to choose");
}
}
}
created by default
var s = new School(1);
var btn = document.createElement('button');
btn.value = "create";
btn.onclick = function(){
s.createStudentAndTeacher();
}
my doubt is when I create the Student object with name "John", return student.id = 0 and student.name = John but when I create the new Student object with name "Elisa", return the same information student.id = 0 and student.name = John and in fact, should return student.id = 1 and student.name = Elisa and if I create new Teacher object with name "Jerry", return the same information student.id = 0 and student.name = John and in fact, should return teacher.id = 0 and teacher.name = Jerry
what I´m doing wrong?
The code has a bug. In the Factory definition, change this
function Factory() {
this.createPerson = function(type, name) {
var person;
var idStudent = 0;
var idTeacher = 0;
to this
function Factory() {
var idStudent = 0;
var idTeacher = 0;
this.createPerson = function(type, name) {
var person;
then use the console, run these lines.
var s = new School();
s.createStudentAndTeacher(); // john
s.createStudentAndTeacher(); // bob
s.persons[0] // id 0:john
s.persons[1] // id 1:bob
Your createPerson is redeclaring idStudent and idTeacher (and resetting them to 0). Try moving that code out of that block.
I have a function PublicGame which I'd like to be using similar to a class. When I create PublicGame I give it a bunch of methods by setting this.methodName = function. The only thing is that I want to call some of these methods when the PublicGame is created. Right now for instance I do this.judge = this.setJudge(), but I know this wont work where I have it because, setJudge isnt defined yet. Should I put this at the bottom of PublicGame? Is my design totally off?
Code:
'use strict';
// var GameSockets = require(‘GameSockets’);
var Games = {};
var id_counter = 0;
var minPlayers = 3;
var maxPlayers = 6;
function PublicGame (players) {
this._id = id_counter++;
this.players = players;
this.gameSocket = new GameSockets.registerPlayers(this.players, this._id, this.playerDisconnects);
this.judge = this.setJudge();
this.killGame = function() {
delete Games[this._id];
};
// When a player presses leave game
this.playerExits = function(playerToRemove) {
// Delete player from players array
this.players.splice(this.players.indexOf(playerToRemove),1);
// If less than min players
if (this.players.length < minPlayers) this.killGame();
// If less than max players
if (this.players.length < maxPlayers) {
this.needsPlayers = true;
}
gameSockets.kickPlayer(playerToRemove);
};
// When a player disconnects without warning, e.g. closes window
this.playerDisconnects = function(playerToRemove) {
// Delete player from players array
this.players.splice(this.players.indexOf(playerToRemove),1);
// If less than min players
if (this.players.length < minPlayers) this.killGame();
// If less than max players
if (this.players.length < maxPlayers) {
this.needsPlayers = true;
}
};
this.selectJudges = function() {
this.judge = this.players.pop();
this.players = this.players.unshift(this.judge);
};
this.setWinner = function(winner) {
this.winner = winner;
};
Games[this._id] = this;
}
If you define your functions on the prototype than you do not need to "wait" for the functions to be defined because the instance will already have them when the constructor's code is called
function PublicGame (players) {
//...
this.judge = this.setJudge();
}
PublicGame.prototype.killGame = function(){
//...
};
PublicGame.prototype.playerExits = function(playerToRemove){
//...
};
PublicGame.prototype.setJudge = function(){
//do whatever
return whatever;
};
So unless your functions need to access some "private" variable (ie defined within the constructor, not a global variable), or other reason requiring it, define it on the prototype instead of defining it in the constructor and it will be ready to use.
You have to use javascript prototype !
Read the comments in the code sample.
/*
* utils functions
*
* dont take care about that
**/
var el = document.getElementById('dbg');
var jj = function(val,sep){return JSON.stringify(val , null , sep || '')}
var log = function(val){el.innerHTML+='<div><pre>'+val+'</pre></div>'};
var counterId = 0;
/************************************************************************/
// You have to use prototype
// here an example of what you can achieve
// we create a Player 'class'
var Player = function( name ){
this.id = counterId ++; //<-- an attribute
this.name = name; //<-- an attribute
this.setLevel(5);//<-- a method called at 'instanciation'
return this;
};
// a method available at instanciation time
Player.prototype.setLevel = function(level){
this.level = level;
return this;
};
// we create a new Player named Toto
var Toto = new Player('Toto');
log('Toto = ' + jj(Toto));//<-- utility function just to log
// we create a new Player named Jane
var Jane = new Player('Jane');
log('Jane = ' + jj(Jane)); //<-- utility function just to log
// we change the Level of Jane
Jane.setLevel(12);
log('Jane.setLevel(12)');//<-- utility function just to log
log('Jane = ' + jj(Jane));//<-- utility function just to log
<div id='dbg'></div>
I am having a lot of trouble writing an object oriented Cat class in Node.js. How can I write a Cat.js class and use it in the following way:
// following 10 lines of code is in another file "app.js" that is outside
// the folder "model"
var Cat = require('./model/Cat.js');
var cat1 = new Cat(12, 'Tom');
cat1.setAge(100);
console.log(cat1.getAge()); // prints out 100 to console
var cat2 = new Cat(100, 'Jerry');
console.log(cat1.equals(cat2)); // prints out false
var sameAsCat1 = new Cat(100, 'Tom');
console.log(cat1.equals(sameAsCat1)); // prints out True
How would you fix the following Cat.js class I have written:
var Cat = function() {
this.fields = {
age: null,
name: null
};
this.fill = function (newFields) {
for(var field in this.fields) {
if(this.fields[field] !== 'undefined') {
this.fields[field] = newFields[field];
}
}
};
this.getAge = function() {
return this.fields['age'];
};
this.getName = function() {
return this.fields['name'];
};
this.setAge = function(newAge) {
this.fields['age'] = newAge;
};
this.equals = function(otherCat) {
if (this.fields['age'] === otherCat.getAge() &&
this.fields['name'] === otherCat.getName()) {
return true;
} else {
return false;
}
};
};
module.exports = function(newFields) {
var instance = new Cat();
instance.fill(newFields);
return instance;
};
If I were to design an object like this, then I would have done like this
function Cat(age, name) { // Accept name and age in the constructor
this.name = name || null;
this.age = age || null;
}
Cat.prototype.getAge = function() {
return this.age;
}
Cat.prototype.setAge = function(age) {
this.age = age;
}
Cat.prototype.getName = function() {
return this.name;
}
Cat.prototype.setName = function(name) {
this.name = name;
}
Cat.prototype.equals = function(otherCat) {
return otherCat.getName() == this.getName()
&& otherCat.getAge() == this.getAge();
}
Cat.prototype.fill = function(newFields) {
for (var field in newFields) {
if (this.hasOwnProperty(field) && newFields.hasOwnProperty(field)) {
if (this[field] !== 'undefined') {
this[field] = newFields[field];
}
}
}
};
module.exports = Cat; // Export the Cat function as it is
And then it can be used like this
var Cat = require("./Cat.js");
var cat1 = new Cat(12, 'Tom');
cat1.setAge(100);
console.log(cat1.getAge()); // 100
var cat2 = new Cat(100, 'Jerry');
console.log(cat1.equals(cat2)); // false
var sameAsCat1 = new Cat(100, 'Tom');
console.log(cat1.equals(sameAsCat1)); // true
var sameAsCat2 = new Cat();
console.log(cat2.equals(sameAsCat2)); // false
sameAsCat2.fill({name: "Jerry", age: 100});
console.log(cat2.equals(sameAsCat2)); // true
I would use a class :
class Cat {
fields = {
age: null,
name: null
};
fill(newFields) {
for(var field in this.fields) {
if(this.fields[field] !== 'undefined') {
this.fields[field] = newFields[field];
}
}
}
getAge() {
return this.fields.age;
}
setAge(newAge) {
this.fields.age = newAge;
}
}
exports.Cat = Cat;
This code is working fine Person.js code here
exports.person=function(age,name)
{
age=age;
name=name;
this.setAge=function(agedata)
{
age=agedata;
}
this.getAge=function()
{
return age;
}
this.setName=function(name)
{
name=name;
}
this.getName=function()
{
return name;
}
};
call object code:
var test=require('./route/person.js');
var person=test.person;
var data=new person(12,'murugan');
data.setAge(13);
console.log(data.getAge());
data.setName('murugan');
console.log(data.getName());
There is error loop hole in answers by #thefourtheye, I will describe those below
Object modelling rules
Create empty new object
Create Filled Object
Only Initial object should be set by machine/code
After Initial object assignment Any changes in your object should happen by user interaction only.
After Initial object assignment Any changes in object by code without user intention is going to add some bugs
Problem Use case :
Eg - So when you create filled object , at that time if any property(somedate) is not having any value then due to below code the default value gets assigned to it(somedate) , which is against object modelling rules.
Bug
Constructor function is given Dual responsibility to create new
& filled object which he mixes up while creating filled object , And
its going to make mistakes.
Means there is some buggy code in your app that is going to set values by it self without users intention
function Cat(age, name, somedate ) { // Accept name and age in the constructor this.name = name || null; this.age = age || null; this.somedate = somedate || new Date(); //there will be lots of usecases like this }
So to solve this Problem i use below JavaScript data model.
So it allows user to create filled object Or new object intentionally only when need any one of them and not messing with each other
class Cat {
constructor(){
this.name = null;
this.age = null;
}
initModel (data) {
this.name = data.name;
this.age = data.age
}
getAge () { return this.age;}
setAge (age) { this.age = age; }
getName () {this.name;}
setName (name) {this.name = name;}
equals (otherCat) {
return otherCat.getName() == this.getName()
&& otherCat.getAge() == this.getAge();
}
fill (newFields) {
for (let field in newFields) {
if (this.hasOwnProperty(field) && newFields.hasOwnProperty(field)) {
if (this[field] !== 'undefined') {
this[field] = newFields[field];
}
}
}
};
}
let cat1 = new Cat();
cat1.initModel({age : 12,name :'Tom'})
cat1.setAge(100);
console.log(cat1.getAge()); // 100
let cat2 = new Cat();
cat2.initModel({age : 100,name : 'Jerry'})
console.log(cat1.equals(cat2)); // false
let sameAsCat1 = new Cat({age : 100,name : 'Tom'});
sameAsCat1.initModel({age : 100,name : 'Tom'})
console.log(cat1.equals(sameAsCat1)); // true
let sameAsCat2 = new Cat();
console.log(cat2.equals(sameAsCat2)); // false
sameAsCat2.fill({name: "Jerry", age: 100});
console.log(cat2.equals(sameAsCat2));
Note :
Constructor is only used For creating new Object
InitModel is only used For creating filled Object
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I would still consider myself at least a 'semi-noob' at JavaScript. I'm trying to get prototypal inheritance down & I want to play with closures. As such, I decided to create a proof-of-concept demo for a currency translator.
I obviously don't have the inheritance 'quite right' and need some feedback there. I'm sure I'll need to change the formula...so I'm not asking about that part. I also promise to post the finished version when done.
My Questions Are:
Why doesn't each instance evaluate as Currency?
Also, any tips you might have on the general design would be great too.
The Code
<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>
UPDATE: Final Version:
As promised. Thanks for the help!
<%# 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>
This would be better design since you do assign the instance variables centrally:
function Currency(country, code, imageURL, name, amount)
{
this.country = country;
this.code = code;
this.imageURL = imageURL;
this.name = name;
this.amount = amount;
}
Next define the method that is to be inherited by the subclasses in Currency's prototype:
Currency.prototype.convertFrom = function (currency, factor) {
this.amount = currency.amount * factor;
}
You can use constructor chaining to save some redundant code:
function Dollar(country, code, imageURL, name) {
Currency.call(this, country, code, imageURL, name);
}
The first sets the inheritance hierarchy, the latter ensures that the right constructor is used when creating a Dollar with new
Dollar.prototype = new Currency();
Dollar.prototype.constructor = Dollar;
The instanceof test will now also succeed. The problem in your code was that your Currency constructor returned an anonymous object. So when assigning new Currency()to Dollar.prototype what you actually assigned was that anonymous object instead of Currency.
First of all, your code doesn't run if you don't define dollar before assigning it a prototype so you may prefer the following order.
Next, the .prototype.constructor should simply be Dollar, and not 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();
ok, as for your alert I do have "dollar is instanceof Currency".
However reais is not instance of Dollar. Reais is instance of currency (by its prototype), but Currency doesn't know Dollar, since it's prototype leads directly by default to Object.