My code does not work correctly, I can not understand why. when you transfer the card to the shoop, he does not add money to it
function Card (money=0) {
this.money = money;
}
Card.prototype.addMoney = function(mon) {
return this.money=this.money+mon;
}
function CreditCard (money =0) {
this.money = money;
}
CreditCard.prototype = Object.create(Card.prototype);
function Shop (card) {
this.card = card
this.money=card.money;
this.addMoney=this.card.addMoney;
}
Shop.prototype = Object.create(Card.prototype);
let card1 = new CreditCard(50);
card1.addMoney(10);//60
card1.addMoney(10);//70
let card2 = new Card(250);
let shop1 = new Shop(card1);
shop1.addMoney(10);//80 but don't work
console.log(card1.money);
this.addMoney = this.card.addMoney;
This is the line with the issue. The function internally references this.money, but since the function is now inside the Shop class, this changes to refer to the shop. So, you have to bind the function to the card. The new line would be:
this.addMoney = this.card.addMoney.bind(this.card);
A shop is not a card. You should not use inheritance here. A shop has a card, so go for composition:
function Shop (card) {
this.companyCard = card
}
Shop.prototype.addMoney = function(mon) {
this.companyCard.addMoney(mon);
};
Shop.prototype.getMoney = function() {
return this.companyCard.money;
};
Related
I've been trying to compare all the series from my objects with the corresponding genre. I managed to display them but I'm practically writing the same code three times, while I'm sure there is a better way.
I'm trying to figure it out how to make the "type" argument match the right genre with the right series, so I don't have to call the same function three times. Maybe I shouldn't use objects into an Array, idk.
Please ask me if there is anything confusying.
'use strict';
//LIST OF SERIES
let listSeries =
[
{film: ['Breaking Bad', 'One of Us Is Lying'], genre: "Drama"},
{film: ['Servant', 'The Midnight Club'], genre: "Horror"},
{film: ['The Office US','Seinfeld'], genre: "Comedy"}
]
// SERIES CLASS
class Series
{
constructor(series, type)
{
this.series = series;
this.type = type;
}
}
//CLASS DISPLAY SERIES LIST WRTING HTML
class Display
{
tableBody = document.getElementById('tableBody');
add(libraryOfSeries)
{
let uiString = `<tr>
<td>${libraryOfSeries.series}</td>
<td class="table-dark">${libraryOfSeries.type}</td>
<button class="btn1 btn-primary" >Read!</button>
</tr>`;
tableBody.innerHTML += uiString;
}
}
// DISPLAY DRAMA SERIES AND CALLING THE ADD METHOD INTO THE CLASS DISPLAY
function displayDrama(series)
{
let dramaSeries = series.find(item => item.genre == "Drama");
for(let i of dramaSeries.film)
{
let currentSeries = new Series(i, dramaSeries.genre);
let display = new Display;
display.add(currentSeries)
}
}
displayDrama(allSeries);
// DISPLAY COMEDY SERIES AND CALLING THE ADD METHOD INTO THE CLASS DISPLAY
function displayComedy(series)
{
let comedySeries = series.find(item => item.genre == "Comedy");
for(let i of comedySeries.film)
{
let currentSeries = new Series(i, comedySeries.genre);
let display = new Display;
display.add(currentSeries)
}
}
displayComedy(allSeries);
// DISPLAY DRAMA SERIES AND CALLING THE ADD METHOD INTO THE CLASS DISPLAY
function displayHorror(series)
{
let horrorSeries = series.find(item => item.genre == "Horror");
for(let i of horrorSeries.film)
{
let currentSeries = new Series(i, horrorSeries.genre);
let display = new Display;
display.add(currentSeries)
}
}
displayHorror(allSeries);
Just use a function with two input variables, then whenever you are trying to call that function, you can decide what you are going to filter.
function displayGenre(series, genreToFilter)
{
let comedySeries = series.find(item => item.genre === genreToFilter);
for(let i of comedySeries.film)
{
let currentSeries = new Series(i, comedySeries.genre);
let display = new Display;
display.add(currentSeries)
}
}
// Calling the function to display drama:
displayGenre(allSeries, "Drama")
// Calling the function to display comedy:
displayGenre(allSeries, "Comedy")
// Calling the function to display horror:
displayGenre(allSeries, "Horror")
Then you can use type variable in the function as well.
TypeError: this.pizzaPlaceEditService.currentPizzaPlace.getPoint is not a function
I found TypeError: is not a function typescript class but I don't think it applies to this situation. Found several more that didn't seem to apply. Here's my redacted class:
export class PizzaPlace {
deliveryArea = [];
getPoint(seq: number): Point {
let result: Point = null;
this.deliveryArea.forEach(function(point:Point) {
if(seq == point.sequence) {
result = point;
}
});
return result;
}
}
Here is my working unit test:
it('should retrieve a point by sequence', () => {
var point1 = new Point();
point1.sequence = 0;
point1.latitude = 5.12;
point1.longitude = 5.12;
var point2 = new Point();
point2.sequence = 1;
point2.latitude = 6.13;
point2.longitude = 6.13;
var point3 = new Point();
point3.sequence = 2;
point3.latitude = 5.25;
point3.longitude = 5.25;
pizzaPlace.deliveryArea = [point1, point2, point3];
expect(pizzaPlace.getPoint(0)).toBe(point1);
expect(pizzaPlace.getPoint(1)).toBe(point2);
expect(pizzaPlace.getPoint(2)).toBe(point3);
expect(pizzaPlace.getPoint(3)).toBe(null);
});
Here is the code generating the error:
onDownClick(): void {
if(this.selectedPoint) {
let currSeq = this.selectedPoint.sequence;
let nextSeq = currSeq + 1;
console.log("Current pizza place:" + JSON.stringify(this.pizzaPlaceEditService.currentPizzaPlace));
console.log("nextSeq:" + nextSeq);
let next = this.pizzaPlaceEditService.currentPizzaPlace.getPoint(nextSeq);
if(next) {
this.pizzaPlaceEditService.currentPizzaPlace.swapPoints(this.selectedPoint, next);
}
}
}
And here is the error:
Current pizza place:{"contactName":"Zaphod Beeblebrox","customerId":"TPGup2lt","deliveryArea":[{"errorMsg":"","sequence":0,"latitude":34.552,"longitude":-84.556},{"errorMsg":"","sequence":1,"latitude":34.711,"longitude":-84.665}],"deliveryZips":[],"paypalAccount":"HB17","settings":null,"shopName":"Donato's Hartland","shopStreet":"1531 Kenesaw Dr","shopCity":"Lexington","shopState":"KY","shopZip":"40515","shopPhone":"(859)555-2637","billStreet":"1531 Kenesaw Dr","billCity":"Lexington","billState":"KY","billZip":"40515","billPhone":"(859)555-2637"}
pizza-place-delivery.component.ts:63:6
nextSeq:1
pizza-place-delivery.component.ts:64:6
TypeError: this.pizzaPlaceEditService.currentPizzaPlace.getPoint is not a function
I have run out of things to try. Any advice appreciated!
Thanks to Artem's excellent input, I was able to figure out that the problem was caused by the fact that I was creating an object from the JSON instead of the object that I wanted and so it was a different type. Evidently, Classes in Typescript are compile time only and are discarded at runtime.
So, based on: How do I initialize a TypeScript object with a JSON object option 4 of the selected answer, I created a serializable.ts.
export interface Serializable<T> {
deserialize(input: Object): T;
}
And then modified my class with the implements:
export class PizzaPlace implements Serializable<PizzaPlace> {
and then added:
deserialize(input): PizzaPlace {
this.paypalAccount = input.paypalAccount;
this.customerId = input.customerId;
...
this.settings = input.settings;
return this;
}
Then, since my web service returns an array of these, I changed my service call:
.subscribe(places => this.deserializePlaces(places));
and added a new function:
deserializePlaces(places: Object[]){
this.pizzaPlaces = [];
places.forEach(obj=> {
let place = new PizzaPlace().deserialize(obj);
this.pizzaPlaces.push(place);
});
}
And this seems to work just fine. Thanks for the input.
I'm trying to write an extension with just using JavaScript. I wrote it with Python through Hello World! code. But, yet in the beginning, my button for menu items is not working. Also, I couldn't add menu item with Hello World! code. I think, I miss something.
The button code is here:
const Lang = imports.lang;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const St = imports.gi.St;
const TimeButton = new Lang.Class({
Name: "Salah Time",
Extends: PanelMenu.Button,
_init: function () {
let box = new St.BoxLayout({
style_class: "system-status-icon"
});
let label = new St.Label({text: "Salah Time"});
box.add_child(label);
this.actor.addActor(box);
}
});
function init() {
}
function enable() {
let but = new TimeButton();
Main.panel._leftBox.insert_child_at_index(but, 1);
}
function disable() {
Main.panel._leftBox.remove_child(but);
}
There is no many tutorial for GJS. I'm already trying to write by reading other extensions.
Thanks.
const Lang = imports.lang;
const Main = imports.ui.main;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const St = imports.gi.St;
const TimeButton = new Lang.Class({
Name: "TimeButton",
Extends: PanelMenu.Button,
_init: function () {
this.parent(null, "TimeButton");
// Icon
this.icon = new St.Icon({
icon_name: "appointment-symbolic",
style_class: "system-status-icon"
});
this.actor.add_actor(this.icon);
// Menu
this.menuItem = new PopupMenu.PopupMenuItem("Salah Time", {});
this.menu.addMenuItem(this.menuItem);
}
});
function init() {
}
function enable() {
let indicator = new TimeButton();
Main.panel.addToStatusArea("should-be-a-unique-string", indicator);
// hide
Main.panel.statusArea["should-be-a-unique-string"].actor.visible = false;
// change icon
Main.panel.statusArea["should-be-a-unique-string"].icon.icon_name = "appointment-soon-symbolic";
// show
Main.panel.statusArea["should-be-a-unique-string"].actor.visible = true;
}
function disable() {
// you could also track "indicator" and just call indicator.destroy()
Main.panel.statusArea["should-be-a-unique-string"].destroy();
}
Hope that helps someone (if you aren't around anymore).
I am trying to do a small JavaScript Lab. In the lab, first I created an Animal object :
function Animal(species, nature) {
this.species = species;
this.nature = nature;
var preys = new Array();
Animal.prototype.getSpecies = function() {
return species;
}
Animal.prototype.getNature = function() {
return nature;
}
Animal.prototype.getPreys = function () {
return preys;
}
Animal.prototype.setNature = function (newNature) {
nature = newNature;
}
Animal.prototype.setSpecies = function (newSpecies) {
species = newSpecies;
}
Animal.prototype.setPrey = function (newPreys) {
preys = newPreys;
}
}
Then, I created a World object which will basically store a number of animal object and separate them according to their nature.
/// <reference path="Animal.js" />
function World() {
var animals = new Array();
animals.push(new Animal("Wolf", "Carnivore"));
animals.push(new Animal("Crocodile", "Carnivore"));
animals.push(new Animal("Sheep", "Omnivore"));
World.prototype.getOmnivores = function () {
return animals.filter(getOmnivores());
}
function getOmnivores(animal) {
}
}
In my getOmnivors function, I can not use the Animal class as a variable. It is a little bit complicated for me cause I am new in JavaScript and regardless of their types we are using var keyword (Or not using in some places such as parameters in functions).
What did I do wrong and how can I fix it? I could not reach the Animal class in my private function getOmnivores. I think program does not understand that it is the class called Animal
I hope I explained well. Have a nice day!
EDIT
Error picture :
Animal is the Class name, you don't need it there. When using filter each element of the array is automatically passed on to the callback function as the first parameter of that function.
Since each element of the array is an instance of the class Animal you can use it straight away.
Also, the syntax {ClassName}.Prototype.{functionName} should not be used within that same Class, because by the time the interpreter reaches that line the Animal Class has not yet been defined. That syntax is used on already existing and defined classes. Use this.{functionName} instead.
function Animal(species, nature) {
this.species = species;
this.nature = nature;
this.preys = new Array();
this.getSpecies = function() {
return this.species;
}
this.getNature = function() {
return this.nature;
}
this.getPreys = function () {
return this.preys;
}
this.setNature = function (newNature) {
this.nature = newNature;
}
this.setSpecies = function (newSpecies) {
this.species = newSpecies;
}
this.setPrey = function (newPreys) {
this.preys = newPreys;
}
}
function World() {
var animals = new Array();
animals.push(new Animal("Wolf", "Carnivore"));
animals.push(new Animal("Crocodile", "Carnivore"));
animals.push(new Animal("Sheep", "Omnivore"));
this.getOmnivores = function () {
return animals.filter(this.filterOmnivores);
}
this.filterOmnivores= function(animal) {
return animal.getNature()=='Omnivore';
}
}
myworld = new World();
console.log(myworld.getOmnivores());
A working fiddle at https://jsfiddle.net/47dyg1q9/
The filter method takes a function as a paramter.
You must provide the function but in your code you are instantly calling the function:
World.prototype.getOmnivores = function () {
return animals.filter(getOmnivores());
}
Remove the parentheses to provide just the function without calling it, or insert an anonymous function:
World.prototype.getOmnivores = function () {
return animals.filter(getOmnivores);
}
// or
World.prototype.getOmnivores = function () {
return animals.filter(function (animal) {
return animal.nature === "omnivore";
});
}
You need to pass the function as an argument, not what it returns.
return animals.filter(isOmnivore);
And isOmnivore becomes
function isOmnivore(animal) {
animal.nature == 'Omnivore';
}
I'm trying to call a method cardSelection() from a function game() but instead I'm getting an error report which throws back to me the whole function with a "has no method cardSelection()" The idea is to access the method through the click of a button, which HTML tag is as follows:
<img id="PlayerCard0" class="card" src="images/Cards/Mario.png" alt="Mario" title="Mario" onclick="game.cardSelection('PlayerCard0')">
I'm not posting the whole Javascript as I believe this to be the case of a mere declaration error, anyhow, game() and cardSelection() were declared as follows:
function game()
{
...
this.cardSelection = function(card)
{
var cardElem = document.getElementById(card);
var id = cardElem.getAttribute("id");
var call = document.getElementById("call");
var select = function(card)
{
var found = 0;
for (var card = 0, totalCards = 5; card < totalCards; card++)
{
if (document.getElementById("PlayerCard" + card + "selected"))
{found++}
}
if (found == 0)
{
call.setAttribute("onclick", "changeHand()");
call.childNodes[0].nodeValue = "Change";
}
if (found < 3)
{
id += "selected"
setAttributes(cardElem,
{
"id" : id,
"style": "position: relative; top: 1em;",
"onclick" : "cardSelection('" + id + "')"
});
}
else { return; }
}
var unselect = function (card)
{
cardElem.removeAttribute("style");
id = id.replace("selected","");
setAttributes(cardElem,
{
"id" : id,
"onclick" : "cardSelection('" + id + "')"
});
var cardNumber = 0;
var found = false;
while (cardNumber < 5 && !found)
{
if (document.getElementById("playerCard" + cardNumber + "selected"))
{found = true;}
cardNumber++;
}
if (!found)
{
call.setAttribute("onclick", "compareHands()");
call.childNodes[0].nodeValue = "Hold";
}
}
if (id.indexOf("selected") >= 0){unselect(card);}
else {select(card);}
}
...
}
How game() is called:
window.onload = function openingScreen()
{
var startGame = document.createElement("a");
startGame.setAttribute("onclick", "game()");
startGame.appendChild(document.createTextNode("Play"));
window.table = document.getElementById("table");
table.appendChild(startGame);
}
The problem you are experiencing is the result of confusion about Objects/Classes/Instances in javascript.
The critical point for you on this issue is the difference between new game() and game();
var foo = new game()
tells the JS engine to create a new object
point that object's Prototype (not prototype) at game's prototype
and then invoke the function game, but for the sake of the body of that function this will refer to the created object.
If the function doesn't return an object, assign our created object to foo (otherwise assign the function's return value to foo
Inside the body of your game function, you have this.cardSelection = function (....
If you simply invoke game as a function, so just game(), without the new keyword, this inside the body of the function will be the window object! So you'll add cardSelection to the window object.
Also importantly: game.cardSelection() is looking for a function named cardSelection as a property on the function game.
Here's an example of using that style that would work:
var foo = function () {
//do interesting stuff
}
foo.bar = function () {
//do interesting stuff related to foo
}
foo.bar();
What you seem to be expecting would need to be written this way:
var game = function () {
this.cardSelection = function () {
//perform card selection!
}
}
var aGame = new game();
aGame.cardSelection();
Or, if cardSelection does not need access to any private properties of the game, it could be written more efficiently as
var game = function () {
//setup the game
};
game.prototype.cardSelection = function () {
//perform card selection
};
var aGame = new game();
aGame.cardSelection();