How can I add another offer to the function - javascript

I am a Javascript learner. I am practicing Javscript object properties and methods.
I want to add another offer to Black pen suppose it will be "10%", how should I go further. Please help.
Is this the correct way of writing code?
function pen(color, size, price) {
this.color = color;
this.size = size;
this.price = price;
}
var pen1 = new pen("Red", "Medium", 20);
var pen2 = new pen("Black", "Large", 35);
var pen3 = new pen("Pink", "Small", 20);
pen.prototype.offer = function() {
return "12%";
}
console.log("You have choosen " + pen1.color + " pen with " + pen1.size + " size. And its price is Rs." + pen1.price);
console.log("You have choosen " + pen2.color + " pen with " + pen2.size + " size. And its price is Rs." + pen2.price);
console.log("You have choosen " + pen3.color + " pen with " + pen3.size + " size. And its price is Rs." + pen3.price + " with " + pen3.offer() + " offer");

You can modify pen2 offer function
pen2.offer = function(){ return parseInt(pen.prototype.offer()) + 10 +"%" ; }

Probably by now you have already got your answer.Here is just another way to explore the prototype
Let use assume that pen is a stationary item.A stationary item can also be a book , a ruler ,a scale and so on.So it is safe to assume that stationary can be a parent object
And pen,ruler,book etc can be child of stationary. & child object can inherit properties.In javascript it is prototype based inheritance.
function Stationary(){
//See there is no options provided here
}
// Adding showItem & offers method to Stationary prototype property
Stationary.prototype.showItem = function(){
console.log("You have choosen " +this.item +" with " +this.color + " having "+ this.size + " size "+". And its price is Rs."
+ this.price +" with "+this.offers(this.offer) +" offer");
}
Stationary.prototype.offers = function(offer){
if(offer){
return offer;
}
else{
return "No offer";
}
}
// Creating an object with some property
var _p1Options ={
item:"Pen",
color:"Indigo",
size:"Large",
price:25,
offer:'12%'
}
//Creating a function which will accept the options
function Item (options){
this.item = options.item || "default";
this.color = options.color || "default";
this.price = options.price || "default";
this.size = options.size || "default";
this.offer = options.offer || "default";
}
//Setting Item's prototype to Stationary's constructor
// It will allow us to inherit all the properties
Item.prototype = new Stationary();
//Create a _p1 object with Item constructor
var _p1 = new Item(_p1Options);
//Item does not have showItem property,it will inherit from Stationary
console.log(_p1.showItem());
So to answer your question you can just create an object like _p1Options & assign property values(including offer) you want instead of hard coding the return value.
Check this jsfiddle for more

Related

Trying to populate string with values from object properties - getting "undefined"

I am trying to solve the below Javascript kata on Codewars but getting "undefined". Can please someone show me the light on what exactly is "undefined". I am struggling to understand what is missing form my code below. Cheers.
Link to challange: https://www.codewars.com/kata/training-js-number-5-basic-data-types-object
I've searched through FreeCodeCamp JS OOP and Basic tutorials / lessons to find similar problems. Searched through StackOverflow, Reddit, and Googled many websites for similar challanges.
Code below:
function animal(name, legs, color) {
this.name = name;
this.legs = legs;
this.color = color;
}
var dog = new animal("dog", 4, "white");
// similar variables set such for other animal objects.
animal.prototype.toString = function animalToString() {
var sent = "This " + this.color + " " + this.name + " has " + this.legs + " legs.";
return sent;
}
return animal.prototype.toString.call();
Expected: This white dog has 4 legs., instead got: undefined
Try this:
function animal(obj){
var newAnimal = {
name: obj.name,
legs: obj.legs,
color: obj.color
};
return "This " + newAnimal.color + " " + newAnimal.name + " has " + newAnimal.legs + " legs.";
}
The purpose of this kata I believe is to introduce you to javascript objects. The issue is thrown when you changed the inputs of the function "animal". If you look at the sample tests in the lower right corner, the inputs being fed into the function you are trying to make should accept only one parameter which is an object with properties name, legs, and color. You changed this input into three separate parameters instead of just one.
Or you could skip the assignment altogether and just access the input directly like so:
function animal(obj){
return "This " + obj.color + " " + obj.name + " has " + obj.legs + " legs.";
}
1) Based on 'instructions'
Give you a function animal, accept 1 parameter obj like this: {name:"dog",legs:4,color:"white"} and return a string like this: "This white dog has 4 legs."
function animal({name, legs, color}) {
return `The ${color} ${name} has ${legs} legs.`;
}
2) Based on what you're supposed to learn
function animal({name, legs, color}) {
this.name = name;
this.legs = legs;
this.color = color;
}
animal.prototype.toString = function animalToString() {
return `The ${this.color} ${this.name} has ${this.legs} legs.`;
}
var dog = new animal({name:"dog", legs:4, color:"white"});
dog.toString();
function animal(obj){
return `This ${obj.color} ${obj.name} has ${obj.legs} legs.`
}
You can try this
function animal(obj){
var a={name:"dog",legs:4,color:"white"}
return "This" + " " + a.color + " " +a.name + " " + "has" + " " + a.legs + " " + "legs.";
}

Edit a variable within an array

I'm attempting to create a Choose Your Own Adventure type of game, and I'm currently trying to write a 'battle' script. What I've got so far is:
var name = "Anon";
var health = 100;
var youAttack = [name + " hits the " + opp + " with his sword", name + " uses magic!", name + " is too scared to fight!"];
var youBattle = function() {
var youBattle = youAttack[Math.floor(Math.random() * 3)];
return youBattle;
};
var opp = "Orc";
var oppHealth = 100;
var oppAttack = ["The " + opp + " hits you with his hammer!", "The " + opp + " does nothing!", "The " + opp + " back hands you!"];
var oppBattle = function() {
var oppBattle = oppAttack[Math.floor(Math.random() * 3)];
return oppBattle;
};
oppBattle();
youBattle();
I've done it like this so the opponent and player names can easily be changed.
What I'm struggling to figure out is how I can add / remove health from both the opponent and the player depending what attack is used. Obviously no health would be removed if the opp / player does nothing.
Is there a way I can do this without a bunch of messy if / else statements?
I was hoping for something easy like name + " hits the " + opp + " with his sword" + health = health - 10; but obviously that didn't work.
Thanks in advance!
http://jsbin.com/qerud/3/edit
Hope this isn't too much code:
var Attack = function(hero,opp,damageReceived,damageGiven,message){
this.message = message;
this.damageGiven = damageGiven;
this.damageReceived = damageReceived;
this.opp = opp;
this.hero = hero;
this.attack = function(opp){
this.hero.health -= damageReceived;
this.opp.health -= damageGiven;
return this.message;
};
};
var Character = function(name,health){
this.name = name;
this.health = health;
};
hero = new Character('Anon',100);
orc = new Character('Orc',150);
attack1 = new Attack(hero,orc,5,0,"The " + orc.name + " back hands you!");
attack2 = new Attack(hero,orc,0,0,hero.name + " is too scared to fight!");
attack3 = new Attack(hero,orc,15,0,"The " + orc.name + " hits you with his hammer!");
attack4 = new Attack(hero,orc,0,25,hero.name + " uses magic!");
attacks = [attack1,attack2,attack3,attack4];
while(hero.health > 0 && orc.health > 0){
console.log(attacks[Math.floor(Math.random() * 4)].attack());
console.log('Hero Health: '+ hero.health);
console.log('Orc Health: '+ orc.health);
}
if(hero.health > 0 ){
console.log(hero.name + ' won');
} else {
console.log('The ' + orc.name + ' won');
}
I can tell you first hand that trying to write this type of code uses a lot of if/else and more statements, regardless of what language you're using. You can use an array to hold the values of your attack patterns:
var attackName = ["Punch", "Sword", "Magic"]
var attackDamage = [3, 5, 4]
function youAttack(ATK, PHit) {
if(playerHit) {
playerDamage = ATK + PHit;
oppHealth = oppHealth - playerDamage;
return oppHeath;
} else {
alert("You missed!");
}
}
But, without seeing exactly what you're doing I cannot say how you should do your attacks and damages. I can only assume. You will need a system of evaluating attacks, misses, etc. that does use IF/ELSE Statements at least somewhere.

multiply two properties inside an object

There are two properties for my bike method.front gear and rear gear.i want another property which will be a new property called gear ratio property which can be obtained by multiplying front and rear gear numbers.the code i have written giving continuous error.how it can be fixed.
function write() {
var bicycle = {
price: 20000,
model: "raleigh",
front_gear: 3,
rear_gear: 7,
gear_ratio: function () {
ratio: this.front_gear * this.rear_gear,
}
}
document.write("this is a " + bicycle.gear_ratio.ratio + " speed bike");
}
window.onload = write;
gear_ratio: function () {
return this.front_gear * this.rear_gear
}
document.write("this is a " + bicycle.gear_ratio() + " speed bike");
Is about the best I can recommend you do. If you still want an object:
gear_ratio: function () {
return {
ratio: this.front_gear * this.rear_gear
}
}
document.write("this is a " + bicycle.gear_ratio().ratio + " speed bike");
It is possible to write something like:
function bike(settings){
// Make settings an object so we can use it always
if (typeof settings != 'object')
settings = {}
// if settings has a price use that, otherwise use 0
this.price = settings.price || 500;
this.model = settings.model || "custom";
this.front_gear = settings.front_gear || 2;
this.rear_gear = settings.rear_gear || 2;
this.__defineGetter__("gear_ratio", function(){
return this.front_gear * this.rear_gear;
});
}
function write() {
var bike1 = new bike({
price: 20000,
model: "raleigh",
front_gear: 3,
rear_gear: 7,
});
var bike2 = new bike({
front_gear: 3,
});
document.write("<br /> bike 1 is a " + bike1.gear_ratio + " speed bike by " + bike1.model + " costing " + bike1.price);
document.write("<br /> bike 2 is a " + bike2.gear_ratio + " speed bike by " + bike2.model + " costing " + bike1.price);
}
Where the function call is implied, however this will require your bike to be an actual instantiated class, and won't work in every browser and is harder to debug. Let me know if you want a better explanation.
change this
window.onload = write;
to this
window.onload = write();
you're calling the function in an inappropriate way

Dynamically change prototype for JavaScript object

My final task is to fully recover object previously saved using JSON. For now JSON only allows to recover data, but not behaviour. A possilbe solution is to create a new object (lets call it obj) and copy data from JSON-recovered-object to obj. But it doesn't look nice for me. What I am asking, is there a way to dynamically change object prototype in JavaScript?
It's how I solve problem at the moment (using self-made copy method):
(this code on JSFiddle)
function Obj() {
this.D = "D";
this.E = "E";
this.F = "F";
this.toString = function () {
return this.D + " * " + this.E + " * " + this.F;
};
this.copy = function (anotherObj) {
for (var property in anotherObj) {
if (isDef(anotherObj[property]) && isDef(this[property])) {
this[property] = anotherObj[property];
}
}
}
}
;
$(document).ready(function () {
var str = $.toJSON(new Obj());
$("#result").append("<p>JSON: " + str + "</p>");
var obj = new Obj();
obj.copy($.parseJSON(str));
$("#result").append("<p>Recovered obj: " + obj.toString() + "</p>");
});
function isDef(variable)
{
return typeof variable !== undefined;
}
There are easier methods provided by many popular JS libraries.
For example, if you are using jQuery, you might use the jQuery.extend() method instead of your copy function like so:
var obj = $.extend(new Obj(), $.parseJSON(str));
Forked jsFiddle here.
EDIT: Based on ideas from this question, I was able to get the restored object to have all the nested functionality as well, see the updated jsFiddle.
The core idea is to use prototypes instead of properties, and then make sure the object restored from JSON (which is just data) is the first parameter to $.extend():
function Obj2() {
this.A = "A";
}
Obj2.prototype.toString = function() {
return this.A;
};
function Obj() {
this.A = new Obj2();
this.D = "D";
this.E = "E";
this.F = "F";
}
Obj.prototype.toString = function() {
return this.A.toString() + " * " + this.D + " * " + this.E + " * " + this.F;
};
var str = $.toJSON(new Obj());
$("#result").append("<p>JSON: " + str + "</p>");
var obj = jQuery.extend($.parseJSON(str), new Obj());
$("#result").append("<p>Recovered obj: " + obj.toString() + "</p>");

How to call a method in class from its replaced implementation?

Hai,
I am trying to understand few concepts in JavaScript. Consider the following code:
function Person(name, age)
{
this.name = name || "no name";
this.age = age || "age not specified";
this.printStr = function()
{
console.log("< " + this.name + ", " + this.age + " >");
};
}
p = new Person("pranav", 26);
p.printStr = function()
{
console.log("this works. also ...." + this.name);
};
p.printStr();
I want to call the implementation of 'printStr' in Person class from within the implementation of 'printStr' function in 'p'.
such that the output should be:
< pranav, 26 >
this works. also ....pranav
Any ideas? :)
The way your code is set up now, you can't do it. When you call Person as a constructor, the object that ends up being p gets set to this. So when you define printStr in the constructor, p gets an attribute called printStr. You then over-write it when you assign the second function.
Two options: A non-answer is to do what pablochan did - have the internal one be called oldPrintStr. Another option is to use the prototype inheritance:
function Person(name, age)
{
this.name = name || "no name";
this.age = age || "age not specified";
}
Person.prototype.printStr = function() {
console.log("< " + this.name + ", " + this.age + " >");
};
Then you can do this:
p = new Person("pranav", 26);
p.printStr = function()
{
Person.prototype.printStr.apply(this);
console.log("this works. also ...." + this.name);
};
p.printStr();
As far as I know there is no real subclassing in JS so to do this you should probably save the old function and then replace it.
p = new Person("pranav", 26);
p.oldPrintStr = p.printStr;
p.printStr = function()
{
p.oldPrintStr();
console.log("this works. also ...." + this.name);
};
p.printStr();
unless you save Person's printStr you can always create a temp Person object solely to extract printStr and call it:
p.printStr = function()
{
print("this works. also ...." + this.name);
(new Person()).printStr.apply(this);
};
but I guess you'll be better off if you make Person's original printStr accessible via prototype:
Person.prototype.printStr = function()
{
print("< " + this.name + ", " + this.age + " >");
};
then you have no need for temp object or saving old function and can do:
Person.prototype.printStr.apply(this);

Categories

Resources