Object constructor syntax error - javascript

In the process of learning JS... it's mai second week from the first day of JS and i have that big problems with syntax
function Customer(name, street, city, state, email, balance) {
this.name = name;
this.street = street;
this.city = city;
this.state = state;
this.email = email;
this.balance = balance;
this.payDownBal = function(amtPaid) {
this.balance -= amtPaid;
};
this.addToBa = function(amtCharged) {
this.balance += amtCharged;
};
}
var cust2 = new Customer("Sally Smith", "234 Main ", "Pittsburgh", "PA", "ssmith#aol.com", 0.00);
cust2.addToBal(15.50);
Customer.prototype.isCreditAvail = true;
Customer.prototype.toString = function() {
return this.name + " lives at " + this.street + " in " +
this.city + " " + this.state + " email : " + this.email +
" and has a balance of $ " + this.balance.toFixed(2) + "Creditworty : " + this.isCredAvail;
}
document.write(cust2.toString());
I can't find the error...can i be helped please ?

You made a simple mistake.
You defined addToBa() function and you are calling function addToBal() which is not defined.
Change the line 17 to call the function addToBa(). (or change the function declaration to addToBal()).

Well, look at line 11 closely, your function declaration:
this.addToBa = function (amtCharged) {
and line 17:
cust2.addToBal(15.50);
It's a typo, "addToBa" on line 11 should be "addToBal".
(Also, there's another typo that won't allow the "isCreditAvail" TRUE boolean value to be referenced in your toString function, on the 3rd-to-last line... change "this.isCredAvail" to "this.isCreditAvail").

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.";
}

javascript alert showing code insted of string

first and foremost i'm new to javascript and coding. second, i'm coding a book store project with javascript with an alert message that shows each customer's total factor. but the alert message shows the code of my function "printFactor" insted of the string that is made by this function. this is my code:
function Book(name, writer, date, price)
{
this.name = name;
this.writer = writer;
this.date = date;
this.price = price;
}
function Customer(name, gender, turn)
{
this.name = name;
this.gender = gender;
this.turn = turn;
this.numberOfBooks = 0;
this.totalSum = 0;
this.bookList = [new Book("-", "-", "-", 0)];
//Functions.
this.addBook = function (newBook) {
this.numberOfBooks++;
this.bookList.push(newBook);
};
this.printFactor = function () {
var message = "";
if (this.numberOfBooks === 0) {
message = "No Books Has Been Added to Book List!";
return (message);
}
else {
message = this.name + " " + this.gender + " Number of Books: " + this.numberOfBooks + " Customer's Turn: " + this.turn + "\nBooks:\n";
var i;
var newMessage;
for (i = bookList.length - 1; i > 0; i--) {
newMessage = bookList[i].name + " " + bookList[i].writer + " " + bookList[i].date + " " + bookList[i].price.toString() +"\n" ;
message += newMessage;
this.totalSum += bookList[i].price;
this.bookList.pop();
}
newMessage = "Total Sum: " + this.totalSum;
message += newMessage;
return (message);
}
};
}
var book = new Book("Faramarz Bio", "Faramarz Falsafi Nejad", "1377/04/29", 13000);
var faramarz = new Customer("faramarz", "Male", 3);
faramarz.addBook(book);
faramarz.addBook(book);
faramarz.addBook(book);
faramarz.addBook(book);
var m = faramarz.printFactor;
window.alert(m);
You need to invoke the function:
var m = faramarz.printFactor();
As is your variable m contains a reference to the function, but you need to call it to get the result.
var m = faramarz.printFactor();
window.alert(m);
You simply don't call your function, this should work.
var m = faramarz.printFactor()
Beside you reference an unexisting variable 'booklist', that should be "this.booklist"
for (i = this.bookList.length - 1; i > 0; i--) {
newMessage = this.bookList[i].name + " " + this.bookList[i].writer + " " + this.bookList[i].date + " " + this.bookList[i].price.toString() +"\n" ;
You need to actually call the function by adding () to the end, like this:
var m = faramarz.printFactor()

How to get the attribute of a JS object from Java?

I know I can use the Invocable class to invoke methods on a class:
import javax.script.{ScriptEngine, ScriptEngineManager, Invocable}
val engine = new ScriptEngineManager().getEngineByExtension("js")
val invoker = engine.asInstanceOf[Invocable]
val person = engine.eval(s"""
new function () {
this.name = "Rick";
this.age = 28;
this.speak = function () {
return this.name + "-" + this.age;
}
};
""")
invoker.invokeMethod(person, "speak") //returns "Rick-28"
But, how do I get the name attribute of the person? I tried invoker.invokeMethod(person, "name") and I got a NoSuchMethodError.
You can cast person to a JSObject and then call person.getMember("name"). Full Java example:
ScriptEngine engine = new ScriptEngineManager()
.getEngineByExtension("js");
JSObject rick = (JSObject) engine.eval("new function () {\n" +
" this.name = \"Rick\";\n" +
" this.age = 28;\n" +
" this.speak = function () {\n" +
" return this.name + \"-\" + this.age;\n" +
" }\n" +
" };");
System.out.println(rick.getMember("name"));
Or, if the object is stored in the engine global scope like in the following javascript source:
rick = function() {
this.name= "Rick";
};
you can then call
engine.eval("rick.name");

Problem with anonymous function and undefined members values

I asked a question here:
Extending javascript literal object
which was solved because I forgot return. Now I didn't forget return and I got undefined again, why ?
<script>
var secretAgent = (function(){
var person = {},
firstName = "James",
lastName = "Bond";
person.WhoAreYou = function() {
alert("My name is " + this.lastName + ", " + this.firstName + " " + this.lastName);
};
return person;
})();
</script>
<script>
secretAgent.WhoAreYou();
</script>
Update: why mine doesn't work whereas I think I did the same thing as the one below that works:
http://enterprisejquery.com/2010/10/how-good-c-habits-can-encourage-bad-javascript-habits-part-1/
//Revealing Module Pattern (Public & Private)
var skillet = (function() {
var pub = {},
//Private property
amountOfGrease = "1 Cup";
//Public property
pub.ingredient = "Bacon Strips";
//Public method
pub.fry = function() {
console.log( "Frying " + pub.ingredient );
};
//Private method
function privateWay() {
//Do something...
}
//Return just the public parts
return pub;
}());
//Public Properties
console.log( skillet.ingredient ); //Bacon Strips
//Public Methods
skillet.fry();
//Adding a public property to a Module
skillet.quantity = 12;
console.log( skillet.quantity ); //12
//Adding a public method to a Module
skillet.toString = function() {
console.log( skillet.quantity + " " +
skillet.ingredient + " & " +
amountOfGrease + " of Grease" );
};
try {
//Would have been successful,
//but can't access private variable
skillet.toString();
} catch( e ) {
console.log( e.message ); //amountOfGrease is not defined
}
You need to declare those properties on the literal itself (rather than separate unrelated variables), like this:
var secretAgent = (function(){
var person = { firstName: "James", lastName: "Bond" };
person.WhoAreYou = function() {
alert("My name is " + this.lastName + ", " + this.firstName + " " + this.lastName);
};
return person;
})();
You can test it out here.
There are two problems here, as I see it.
You did forget the return, again. :-) The WhoAreYou function doesn't actually return anything, it just alerts. Hence secretAgent.WhoAreYou() returns undefined too.
The alert shows "My name is undefined, undefined undefined". This is because of the scope of the variables used. You assign the WhoAreYou to person, and within the body you reference this.lastName. The this here refers to the person variable, and as you can see this object does not have a lastName property.
There are two ways then that you can fix the latter issue. Firstly, by adding the name variables to the person object:
var secretAgent = (function(){
var person = {};
person.firstName = "James";
person.lastName = "Bond";
person.WhoAreYou = function() {
alert("My name is " + this.lastName + ", " + this.firstName + " " + this.lastName);
};
return person;
}
)();
// Although the first three lines would be more natural as:
var person = { firstname: "James", lastName: "Bond" };
Secondly, you can instead choose to drop the this reference, which will instead refer to the local variables you just defined:
var secretAgent = (function(){
var person = {},
firstName = "James",
lastName = "Bond";
person.WhoAreYou = function() {
alert("My name is " + lastName + ", " + firstName + " " + lastName);
};
return person;
}
)();
You'll of course need to add appropriate returns to the WhoAreYou function in both examples.
Remove "this" from the variables since you are setting them as a var with in the anonymous function, using this points to that function and not "Person" which is where you are now calling them.
<script>
var secretAgent = (function(){
var person = {},
firstName = "James",
lastName = "Bond";
person.WhoAreYou = function() {
alert("My name is " + lastName + ", " + firstName + " " + lastName);
};
return person;
}
)();
</script>
<script>
secretAgent.WhoAreYou();
</script>
example here: JSFiddle
Why not just:
var secretAgent = {
firstName: "James",
lastName: "Bond",
whoAreYou: function() {
alert("My name is " + this.lastName + ", " +
this.firstName + " " + this.lastName);
}
};
The way you defined firstName and lastName are not fields to object person itself. But they are upper values to function WhoAreYou. So you could write the function like this:
person.WhoAreYou = function() {
alert("My name is " + this.lastName + ", " + this.firstName + " " + this.lastName);
};
Its like if those were private variables to the function. The alternative is declaring as filelds to the object itself like this:
var person = {
firstName: "James",
lastName: "Bond",
};
The the method whould work as you wrote it.
The variable this is person in your case, also firstName and lastName are defined as local variables, but not as properties of the person, so you can just access them within the anonymous function by names:
var secretAgent = (function(){
var person = {},
firstName = "James",
lastName = "Bond";
person.WhoAreYou = function() {
alert("My name is " + lastName + ", " + firstName + " " +lastName);
};
return person;
})();
secretAgent.WhoAreYou();

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