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

LVL 1
rwniceingAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

RobOwner (Aidellio)Commented:
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.

http://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

0
rwniceingAuthor Commented:
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
0
RobOwner (Aidellio)Commented:
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

0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

rwniceingAuthor Commented:
//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

0
RobOwner (Aidellio)Commented:
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.
0
rwniceingAuthor Commented:
In other words, price in function is private that can be changed unless using closure with return statement
0
rwniceingAuthor Commented:
I heard privated variable in function  can be accessable by externally with  some method, Did you hear it before ?
0
RobOwner (Aidellio)Commented:
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.
0
RobOwner (Aidellio)Commented:
In other words, price in function is private that can be changed unless using closure with return statement
yes, As I understand it.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
rwniceingAuthor Commented:
Thanks for your reply
0
RobOwner (Aidellio)Commented:
Can you please review the grade?  It should be an A.

http://support.experts-exchange.com/customer/portal/articles/481419
0
rwniceingAuthor Commented:
Thanks for your reply, request attention is submitted for Grade A
0
RobOwner (Aidellio)Commented:
No problem and thanks for getting the grade changed.  I'm really enjoying our discussions :)
0
rwniceingAuthor Commented:
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
0
RobOwner (Aidellio)Commented:
I'm if to bed now but will monitor for any new questions you have
0
rwniceingAuthor Commented:
Thanks for your reply.
0
rwniceingAuthor Commented:
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

0
RobOwner (Aidellio)Commented:
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.
0
rwniceingAuthor Commented:
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
0
RobOwner (Aidellio)Commented:
that's right... prototype will update any existing instantiated objects with the new code.  Again I said this in my other post :)
0
rwniceingAuthor Commented:
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 ?
0
RobOwner (Aidellio)Commented:
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
0
RobOwner (Aidellio)Commented:
0
rwniceingAuthor Commented:
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
0
RobOwner (Aidellio)Commented:
no problem.

Did you read this article: http://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.
0
rwniceingAuthor Commented:
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

0
RobOwner (Aidellio)Commented:
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.
0
RobOwner (Aidellio)Commented:
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

0
rwniceingAuthor Commented:
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
0
RobOwner (Aidellio)Commented:
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
0
rwniceingAuthor Commented:
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

0
RobOwner (Aidellio)Commented:
Yep, you've got it now :)
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
JavaScript

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.