Link to home
Start Free TrialLog in
Avatar of rwniceing
rwniceing

asked on

Prototype Javascript-2

Dear Experts,

I have set up cook menu price calculation function for two customers, Bob and John to pay after ordering food and drink. It is easy using function, and now the owner restaurant changes the price formula by using the prototype, now the new price is changing to replace the old price formula so they need to pay new price.

But the console.log("Bob pay new price:", guest_Bob_price.price(2,3)); is not working
because  prototype property "price" is conflict to  this.price in the function. It will
be solved if using  prototype pricechg property to replace price property . I want use the same price  property before and after the formula change. How to do it on javascript prototype ?
The following code is not working at the console.log("Bob pay new price:", guest_Bob_price.price(2,3));

please advise

Rwniceing

<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head>
<title>Title</title>

<script type="text/javascript">

function CookMenu(food,drink){
	//console.log(CookMenu.prototype.pricechg);//undefined
	if (CookMenu.prototype.pricechg==undefined){
	//this.price=100*food+200*drink;
    return this;
	}
} 
function start(){
var guest_Bob_price = new CookMenu(2,3);
var guest_John_price = new CookMenu(5,6);

console.log("Bob pay old price:", guest_Bob_price.price);
console.log("John pay old price:", guest_John_price.price);

//-Menu price might change if input value=1
if (document.getElementById("owner").value==1){
CookMenu.prototype={price:function(food,drink){ return 300*food+700*drink; }};
var owner_restaurant=new CookMenu(2,3);
}

var guest_Bob_price = new CookMenu(2,3);
var guest_John_price = new CookMenu(2,3);
console.log("Bob pay new price:", guest_Bob_price.price(2,3));
console.log("John pay new price:", guest_John_price.price(2,3));
}

</script>
<body onload="start();">
<div>
Prototype javascript tutorial, for example, restaurant menu price change
</div>
<div>
<input type="text" name="owner" id="owner" value="1" />
</div>
</body>
</html>

Open in new window

Avatar of Rob
Rob
Flag of Australia image

http://jsbin.com/xecak/1/edit

You don't need prototype it's overkill and there's no reason to use it when you can define the function within your object.

https://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/A_13138-Javascript-is-just-an-Object.html

New Code:
window.onload = function() {
	start();
};

function CookMenu(_food, _drink){
	var food = _food;
	var drink = _drink;

	this.price = function() { 
		return 300*food+700*drink; 
	};


} 
function start(){
	var guest_Bob_price = new CookMenu(2,3);
	var guest_John_price = new CookMenu(5,6);

	console.log("Bob pay old price:", guest_Bob_price.price());
	console.log("John pay old price:", guest_John_price.price());

	//-Menu price might change if input value=1
	if (document.getElementById("owner").value==1) {
		var owner_restaurant=new CookMenu(2,3);
	}

	guest_Bob_price = new CookMenu(2,3);
	guest_John_price = new CookMenu(2,3);
	console.log("Bob pay new price:", guest_Bob_price.price(2,3));
	console.log("John pay new price:", guest_John_price.price(2,3));
}

Open in new window

Avatar of rwniceing
rwniceing

ASKER

I know how to use it  in function, and I just make it possible for prototype
whatever that is good way to do it or not, just let me have prototype tutorial
at this simple example,the new price is updated during the menu program is running
Personally you would only use prototype to override or add your own functions to objects where the code is too complex to edit (or minified) such as jQuery or it's inherent to the browser such as the String object.

but to humour you, and assume that the CookMenu class has been defined in an external script that you do not want to edit:

window.onload = function() {
	start();
};

function CookMenu(_food, _drink){
	this.food = _food;
	this.drink = _drink;
}

function start(){

	CookMenu.prototype.price = function() {
		return 300*this.food+700*this.drink; 
	};

	// after prototype
	var guest_Bob_price = new CookMenu(2,3);
	var guest_John_price = new CookMenu(5,6);

	console.log("Bob pay old price:", guest_Bob_price.price());
	console.log("John pay old price:", guest_John_price.price());

	//-Menu price might change if input value=1
	if (document.getElementById("owner").value==1) {
		var owner_restaurant=new CookMenu(2,3);
	}

	guest_Bob_price = new CookMenu(2,3);
	guest_John_price = new CookMenu(2,3);
	console.log("Bob pay new price:", guest_Bob_price.price(2,3));
	console.log("John pay new price:", guest_John_price.price(2,3));
}

Open in new window

//this.price=100*food+200*drink;

Sorry I commented that code line  in original code that is for old price formula,
after adding it back to original as follows attached code, it will console output like
this

Bob pay old price :800
John pay old price:1700
Uncaught TypeError:number is not a function at line 32 //---console.log("Bob pay new price:", guest_Bob_price.price(2,3));

The error is I believer  because of using price in prototye that conflict to price in the function

I expect the result with same price property in prototype and in function
Bob pay old price :800
John pay old price:1700
Bob pay new price :2700
John pay new price:2700

<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head>
<title>Title</title>

<script type="text/javascript">

function CookMenu(food,drink){
	//console.log(CookMenu.prototype.pricechg);//undefined
	if (CookMenu.prototype.pricechg==undefined){

this.price=100*food+200*drink;

    return this;
	}
} 
function start(){
var guest_Bob_price = new CookMenu(2,3);
var guest_John_price = new CookMenu(5,6);

console.log("Bob pay old price:", guest_Bob_price.price);
console.log("John pay old price:", guest_John_price.price);

//-Menu price might change if input value=1
if (document.getElementById("owner").value==1){
CookMenu.prototype={price:function(food,drink){ return 300*food+700*drink; }};
var owner_restaurant=new CookMenu(2,3);
}

var guest_Bob_price = new CookMenu(2,3);
var guest_John_price = new CookMenu(2,3);
console.log("Bob pay new price:", guest_Bob_price.price(2,3));
console.log("John pay new price:", guest_John_price.price(2,3));
}

</script>
<body onload="start();">
<div>
Prototype javascript tutorial, for example, restaurant menu price change
</div>
<div>
<input type="text" name="owner" id="owner" value="1" />
</div>
</body>
</html>

Open in new window

You can't do it like that because the original definition of the class doesn't give you access to the private variables and you do not "save" the food and drink values to your object, so the prototype can't access them.
In other words, price in function is private that can be changed unless using closure with return statement
I heard privated variable in function  can be accessable by externally with  some method, Did you hear it before ?
yes I have but I haven't got it to work and it's not a reliable method.  you should use getters and setters if you want private variables.
ASKER CERTIFIED SOLUTION
Avatar of Rob
Rob
Flag of Australia image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks for your reply
Can you please review the grade?  It should be an A.

http://support.experts-exchange.com/customer/portal/articles/481419
Thanks for your reply, request attention is submitted for Grade A
No problem and thanks for getting the grade changed.  I'm really enjoying our discussions :)
How Bob change property through prototype will affect John's accessing property result ?
Could you provide a hint code for next new thread if need ?

And I fixed the code with pricechg instead of price for previous post code attached
I'm if to bed now but will monitor for any new questions you have
Thanks for your reply.
my memo or reminder :
the answer is yes to this topic post that you can use the same price property
for pay price before and after menu price change

After studying the online javascript for OOP and prototype at this detailed  tutorial link at
https://www.youtube.com/watch?v=pu08qQCmw8I 
https://www.youtube.com/watch?v=EBoUT2eBlT4
I found it will work to change  the menu price property in CookMenu() function  by the restaurant owner   if the id="owner" with value is equal to 1 , the way to do  it that  is set parent and child function for CookMenu and OwnerCookMenu respectively, and change the price formula through prototype from child OwnerCookMenu,prototype,finally it show the exact output I want using the same price property before and after owner change the menu price

console.log output for the following attached code
Bob pay old price :800
John pay old price:1700
Bob pay new price :2700
John pay new price:2700


<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<head>
<title>Title</title>

<script type="text/javascript">
//parent object
function CookMenu(){
	//console.log(CookMenu.prototype.pricechg);//undefined
	//if (CookMenu.prototype.pricechg==undefined){
	this.parentname="CookMenu";
	this.price=function(food,drink){ return 100*food+200*drink;}
    //
} 
// Child for restaurant owner
function OwnerCookMenu(){
	//console.log(CookMenu.prototype.pricechg);//undefined
	//if (CookMenu.prototype.pricechg==undefined){
	this.childname="OwnerCookMenu";
	this.ownerprice=function(food,drink){ return 100*food+200*drink; }
   
	//}
} 
function start(){
OwnerCookMenu.prototype =new CookMenu();
//Customer Bob and John
var Bob = new OwnerCookMenu();
var John = new OwnerCookMenu();
console.log("Bob pay old price:" ,Bob.price(2,3));
console.log("Bob pay old price:" ,John.price(5,6));

//-Now restaurant owner change menu price if owner value in the page is set to 1
if (document.getElementById("owner").value==1){
OwnerCookMenu.prototype.price= function(food,drink){ return 300*food+700*drink; }
}
//Customer Bob and John need to pay new price after 2 seconds, and he paid the old price for 800 & 1700
console.log("Bob pay new price:" ,Bob.price(2,3));
console.log("Bob pay new price:" ,John.price(2,3)); 
}
<body onload="start();">
<div>
Prototype javascript tutorial, for example, restaurant menu price change
</div>
<div>
<input type="text" name="owner" id="owner" value="1" />
</div>
</body>
</html>

Open in new window

That is exactly what I shouted you in your  other question! Prototype inherits the objects properties and becomes a "child" when used with the new keyword.
And new object for Bob and John both are also NOT necessary for this topic requirement if
there are many customers such as 10000  Bob , Jonn, Joe....etc.

just  set

pay=OwnerCookMenu.prototype =new CookMenu();
onsole.log("Bob pay old price:" ,pay.price(2,3));//800
console.log("Bob pay old price:" ,pay.price(5,6));//1700
if (document.getElementById("owner").value==1){
OwnerCookMenu.prototype.price= function(food,drink){ return 300*food+700*drink; }
}
onsole.log("Bob pay old price:" ,pay.price(2,3));//2700
console.log("Bob pay old price:" ,pay.price(5,6));//2700
that's right... prototype will update any existing instantiated objects with the new code.  Again I said this in my other post :)
Rob, actually, prototype is not reserved word for javascript. When I change it
from "prototype" to "pro" , the code also show the same output. Right ? Why ?

OwnerCookMenu.prototype =new CookMenu()

OwnerCookMenu.pro =new CookMenu()

it seems  prototype or pro  is just OwnerCookMenu's extend object, right ?
No, that's not right, it will not have the same affect.

OwnerCookMenu.prototype = new CookMenu();  // copies all variables and functions from CookMenu into OwnerCookMenu

OwnerCookMenu.pro = new CookMenu();  // assigns a new CookMenu object to a "pro" variable in the OwnerCookMenu object
You are right ,Yes prototype is reserved word for javascript

it will be issue if prototype changed to pro since the pro won't inherit all from parent of CookMenu when Bob is instantiating from new CookMenu. Why I get the same output because I did not use Bob with "new" and replace Bob by pay as follows,


pay= OwnerCookMenu.pro =new CookMenu();
console.log("Bob pay old price:",pay.price(2,3));

pay= OwnerCookMenu.pro is just variable as creating for Bob but no any prototype features

Thanks for your reply

Rwniceing
no problem.

Did you read this article: https://www.experts-exchange.com/Programming/Languages/Scripting/JavaScript/A_13138-Javascript-is-just-an-Object.html

Did you work through it slowly?  I know it requires a lot of patience but all your answers are there.
And actually, change the CookMenu formula that  it is NO need doing with prototype just accessing price through  pay=new CookMenu();  AND pay.price=function(food,drink){ return 300*food+700*drink;}   as code follows without any prototype. So I need to think about  when and where I need to use prototype code  with consideration with  child and parent relation and  its iheritance.

<!DOCTYPE html><html><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><head>
<script type="text/javascript">
//parent object
function CookMenu(){
	this.parentname="CookMenu";
	this.currency="$US";
	this.price=function(food,drink){ return 100*food+200*drink;}
    } 
// Child for restaurant owner
 function start(){
pay=new CookMenu();
//Customer Bob and John
console.log("Bob pay old price:",pay.price(2,3));
console.log("John pay old price:" ,pay.price(5,6));
//-Now restaurant owner change menu price if owner value in the page is set to 1
if (document.getElementById("owner").value==1){
console.log("price change----------------");
pay.price= function(food,drink){ return 300*food+700*drink; 
}
}
//Customer Bob and John need to pay new price after 2 seconds, and he paid the old price for 800 & 1700
console.log("Bob pay new price:" ,pay.price(2,3));
console.log("Bob pay new price:" ,pay.price(2,3)); 
}
</script>
<body onload="start();">
<div>
No Prototype javascript tutorial, for example, restaurant menu price change
</div>
<div>
<input type="text" name="owner" id="owner" value="1" />
</div>
</body>
</html>

Open in new window

In Your example above, you have modified the price function for only that one instance of the object pay.  If you were to create another instance of new CookMenu(); then you'll find it will have the old price function.
See below how I've created another instance called pay2.  We modify the price function on the pay object but not the pay2 object so the result is different.

//parent object
function CookMenu(){
	this.parentname="CookMenu";
	this.currency="$US";
	this.price=function(food,drink){ return 100*food+200*drink;}
} 
// Child for restaurant owner
function start(){
	pay=new CookMenu();
	pay2 = new CookMenu();
	//Customer Bob and John
	console.log("Bob pay old price:",pay.price(2,3));
	console.log("John pay old price:" ,pay.price(5,6));
	//-Now restaurant owner change menu price if owner value in the page is set to 1
	if (document.getElementById("owner").value==1){
		console.log("price change----------------");
		pay.price= function(food,drink){ return 300*food+700*drink; 
									   }
	}
	//Customer Bob and John need to pay new price after 2 seconds, and he paid the old price for 800 & 1700
	console.log("Bob pay new price:" ,pay.price(2,3));
	console.log("Bob pay new price:" ,pay.price(2,3)); 

	console.log("Bob pay old? price:" ,pay2.price(2,3));
	console.log("Bob pay old? price:" ,pay2.price(2,3)); 

}

Open in new window

function CookMenu(){
      this.parentname="CookMenu";
      this.currency="$US";
      this.price=function(food,drink){ return 100*food+200*drink;}
    }
// Child for restaurant owner
 function start(){
pay=new CookMenu();
//Customer Bob and John
console.log("Bob pay old price:",pay.price(2,3)); //800
console.log("John pay old price:" ,pay.price(5,6));//1700
//-Now restaurant owner change menu price if owner value in the page is set to 1
if (document.getElementById("owner").value==1){
console.log("price change----------------");
pay.price= function(food,drink){ return 300*food+700*drink;
}
}
//Customer Bob and John need to pay new price after 2 seconds, and he paid the old price for 800 & 1700
console.log("Bob pay new price:" ,pay.price(3,3)); //3000
console.log("John pay new price:" ,pay.price(3,6)); //5100
}

I got the correct result even using the same pay , 3000=3*300+3*700 and 5100=3*300+6*700 from new formula

it seems no need to use pay2
I think you're missing my point. I created pay2 to show you that you're only affecting the pay object when you assign the price function. If you'd used prototype then pay2 would skew the same results ie 3000 & 5100
I know what you mean
pay.price will change only pay object's price property ,and is not able to change CookMenu's price property.CookMenu is function or class and is parent of pay and pay2 shown on pay instanceof  CookMenu. The old formual is still the same and can be accessed by other object of pay2 if want to get  back old formula.

The console output for following code with pay and pay2.
-true true
-function (food,drink){ return 100*food+200*drink;}
-function (food,drink){ return 100*food+200*drink;}
-Bob pay old price:pay.price= 800
-John pay old price:pay.price 1700
-price change----------------
-Bob pay new price:pay.price 2700
-John pay new price:pay.price 5700
-Bob pay old? price:pay2.price 800
-John pay old? price:pay2.price 1700
-function (food,drink){ return 300*food+700*drink;}
-function (food,drink){ return 100*food+200*drink;}
-function CookMenu(){
      this.parentname="CookMenu";
      this.currency="$US";
      this.price=function(food,drink){ return 100*food+200*drink;}
}
-CookMenu {parentname: "CookMenu", currency: "$US", price: function}
currency: "$US"
parentname: "CookMenu"
price: function (food,drink){ return 300*food+700*drink;}
__proto__: CookMenu



function CookMenu(){
	this.parentname="CookMenu";
	this.currency="$US";
	this.price=function(food,drink){ return 100*food+200*drink;}
} 
// Child for restaurant owner
function start(){
	pay=new CookMenu();
	pay2 = new CookMenu();
	console.log (pay instanceof CookMenu,pay2 instanceof CookMenu);
	console.log (pay.price);
	console.log (pay2.price);
	//Customer Bob and John
	console.log("Bob pay old price:pay.price=",pay.price(2,3));
	console.log("John pay old price:pay.price" ,pay.price(5,6));
	//-Now restaurant owner change menu price if owner value in the page is set to 1
	if (document.getElementById("owner").value==1){
		console.log("price change----------------");
		pay.price= function(food,drink){ return 300*food+700*drink;}
	}

	//Customer Bob and John need to pay new price after 2 seconds, and he paid the old price for 800 & 1700
	console.log("Bob pay new price:pay.price" ,pay.price(2,3));
	console.log("John pay new price:pay.price" ,pay.price(5,6)); 
	console.log("Bob pay old? price:pay2.price" ,pay2.price(2,3));
	console.log("John pay old? price:pay2.price" ,pay2.price(5,6)); 
	console.log (pay.price);
	console.log (pay2.price);
	console.log(CookMenu);
	console.log(pay);
}

Open in new window

Yep, you've got it now :)