I have three methods in an object.
2 of them work properly, when third is printed - it prints out the code itself, not function. Here is the code and how it looks in console:
function Students(name, lastname, grades){
this.name = name;
this.lastname = lastname;
this.grades = grades;
this.addGrade = function(a){
this.grades.push(a);
}
this.printData = function(){
console.log("Name: " + this.name);
console.log("Grades: " + this.grades);
console.log("Average: " + this.gradeAvg);
}
this.gradeAvg = function(){
console.log("blabla");
}
}
var StudentasA = new Students("Petras", "Petrauskas", [8, 9, 9, 8, 7]);
var StudentasB = new Students("Jurgis", "Jurgauskas", [6, 7, 5, 4, 9]);
StudentasA.printData();
StudentasA.addGrade(28);
StudentasA.printData();
console:
console view
You need to call the function
this.gradeAvg()
// ^^
function Students(name, lastname, grades){
this.name = name;
this.lastname = lastname;
this.grades = grades;
this.addGrade = function(a){
this.grades.push(a);
}
this.printData = function(){
console.log("Name: " + this.name);
console.log("Grades: " + this.grades);
console.log("Average: " + this.gradeAvg());
// ^^
}
this.gradeAvg = function(){
return this.grades.reduce(function (a, b) { return a + b; }) / this.grades.length;
}
}
var StudentasA = new Students("Petras", "Petrauskas", [8, 9, 9, 8, 7]);
var StudentasB = new Students("Jurgis", "Jurgauskas", [6, 7, 5, 4, 9]);
StudentasA.printData();
StudentasA.addGrade(28);
StudentasA.printData();
Your code never actually calls the function.
Instead, you concatenate the function itself directly into the string.
You want parentheses.
Related
var peopleFactory = function(name, age, height) {
var temp = {};
this.name = name;
this.age = age;
this.height = height;
temp.printPerson = function() {
console.log(this.name + '' + this.age + '' + this.height);
document.write(this.name + '' + this.age + '' + this.height);
};
return temp;
};
var person1 = peopleFactory('tanmay', 27, 5.11);
var person2 = peopleFactory('chinmay', 37, 5.12);
person1.printPerson();
person2.printPerson();
Not sure but here you go. Just make it a class.
class peopleFactory {
constructor(name, age, height) {
this.name = name;
this.age = age;
this.height = height;
}
printPerson() {
return this.name + ' ' + this.age + ' ' + this.height;
};
};
var person1 = new peopleFactory('tanmay', 27, 5.11);
console.log(person1.printPerson())
You should not be using this in your factory as it's a reference to the global object (unless you want to call your factory with the new keyword. But then, it wouldn't be a factory anymore).
Instead, you could be using another local object where you would store your object's private data. By doing that, your printPerson() function becomes a closure and can access data inside that local object and will be able to print it once it's invoked.
var peopleFactory = function(name, age, height) {
var temp = {}, instance = {};
temp.name = name;
temp.age = age;
temp.height = height;
instance.printPerson = function() {
console.log(temp.name + ' ' + temp.age + ' ' + temp.height);
document.write('<br/>' + temp.name + ' ' + temp.age + ' ' + temp.height);
};
return instance;
};
var person1 = peopleFactory('tanmay', 27, 5.11);
var person2 = peopleFactory('chinmay', 37, 5.12);
person1.printPerson();
person2.printPerson();
The following code does not work as desired (jsFiddle):
function makeFoo(a, b) {
var foo = new Foo();
Foo.apply(foo, arguments);
return foo;
}
var Foo = function(a, b) {
console.log(
"This should be called once. "+
"a=\"" + a + "\", " +
"b=\"" + b + "\", "
);
this.a = a;
this.b = b;
}
Foo.prototype.go = function() {
console.log("a: " + this.a);
console.log("b: " + this.b);
};
var foo = makeFoo("Hello", "World");
foo.go();
Expected output:
This should be called once. a="Hello", b="World"
a: Hello
b: World
Actual output:
This should be called once. a="undefined", b="undefined"
This should be called once. a="Hello", b="World"
a: Hello
b: World
That's because you call Foo twice: via new and via function call.
I think with new Foo() you only wanted to create an object which inherits from Foo.prototype. To achieve that, use Object.create(Foo.prototype) instead.
function makeFoo(a, b) {
var foo = Object.create(Foo.prototype);
var result = Foo.apply(foo, arguments);
return Object(result) === result ? result : foo;
}
var Foo = function(a, b) {
console.log(
"This should be called once. "+
"a=\"" + a + "\", " +
"b=\"" + b + "\", "
);
this.a = a;
this.b = b;
}
Foo.prototype.go = function() {
console.log("a: " + this.a);
console.log("b: " + this.b);
};
var foo = makeFoo("Hello", "World");
foo.go();
But that's just a hack, which you are required to use in ECMAScript 5 because there is no way to instantiate a constructor with an arbitrary number of arguments.
Constructors should be instantiated, not called as functions. In ECMAScript 6, you can do it with Reflect.construct.
function makeFoo(a, b) {
return Reflect.construct(Foo, arguments);
}
var Foo = function(a, b) {
console.log(
"This should be called once. "+
"a=\"" + a + "\", " +
"b=\"" + b + "\", "
);
this.a = a;
this.b = b;
}
Foo.prototype.go = function() {
console.log("a: " + this.a);
console.log("b: " + this.b);
};
var foo = makeFoo("Hello", "World");
foo.go();
Try this:
function makeFoo(a, b){
var foo = new Foo(a,b);
return foo;
}
Why the undefined gets outputted instead of the object properties.
Created a function, defined setters for the parameters and function to output the string consisting of the parameters.
Below is the snippet for the app.js file.
// app.js
function Fruit(theColor, sweetness, theName, theOrigin) {
//properties
this.theColor = theColor;
this.sweetness = sweetness;
this.theName = theName;
this.theOrigin = theOrigin;
//functions
this.showName = function () {
console.log("This is a " + this.theName);
};
this.showLand = function () {
this.theOrigin.forEach(function (arg) {
console.log("Grown in: " + arg);
});
};
}
var mango = new Fruit("Yellow", 9, "Mango", ["India", "Central America"]);
console.log(mango.showName() + " " + mango.showLand());
This line:
console.log(mango.showName() + " " + mango.showLand());
calls those functions, then outputs their return values with a space between them. Neither showNames nor showLand returns anything, and so calling them gives you the result undefined.
If you just want to call those, just call them, without using console.log to output their result. E.g., replace:
console.log(mango.showName() + " " + mango.showLand());
with
mango.showName();
mango.showLand();
If you want them to return, rather than display, their result, edit them to do so. You'll have to decide how you want showLand to separate lines (e.g., with a \n, or by returning an array, etc.).
For instance, this showName will return a string, and showLand will return an array:
//functions
this.showName = function () {
return "This is a " + this.theName;
};
this.showLand = function () {
return this.theOrigin.map(function (arg) {
return "Grown in: " + arg;
});
};
which you could then call like this:
console.log(mango.showName() + ". " + mango.showLand().join(", "));
Live Example:
function Fruit(theColor, sweetness, theName, theOrigin) {
//properties
this.theColor = theColor;
this.sweetness = sweetness;
this.theName = theName;
this.theOrigin = theOrigin;
//functions
this.showName = function () {
return "This is a " + this.theName;
};
this.showLand = function () {
return this.theOrigin.map(function (arg) {
return "Grown in: " + arg;
});
};
}
var mango = new Fruit("Yellow", 9, "Mango", ["India", "Central America"]);
console.log(mango.showName() + ". " + mango.showLand().join(", "));
I have two Jquery function. How do I set the execution order so that function B would only be called after function A, (reason behind is that Function A set a value to a variable IdstoExclude that is getting passed as a parameter to function B.
Below is what i tried but no luck:
var IDstoExclude = "123";
callListService('getArticleTypelistById', 'Atid', 87, 5, '#MainStory', '#tmplFeaturePanel', IDstoExclude);
callListService('getArticleTypelistById', 'Atid', 87, 10, '#LeftSideContent1', '#tmplLeftSideContent1', IDstoExclude);
function callListService(webServiceName, parameterName, parameterValue, noOfItems, domElement, templName, exclIDs) {
//set a default value for the template name * exclIDs
templName = templName || "#FeaturedSubStories";
//exclIDs = exclIDs || "123,12";
var inputParameters = webServiceName.toLowerCase() + ':' + parameterName.toLowerCase() + ':' + parameterValue + ':noofitems:' + noOfItems + ':excludeids:' + exclIDs;
var clientcode = getCryptoToken(inputParameters);
//Build JSONp query
eval("data={" + parameterName.toLowerCase() + ":" + parameterValue + ", noofitems: " + noOfItems + ", excludeids:" + exclIDs + ", clientcode:'" + clientcode + "' }");
$.getJSON('https://abc.com/Service.svc/' + webServiceName + '?callback=?', data, function (data2) {
var template = $.templates(templName);
var htmlOutput = template.render(data2);
$(domElement).append(htmlOutput);
IDstoExclude = data2.IdsInThisList;
});
Tried below but no luck: var IDstoExclude = "123";
function callService1() {
return $.ajax()
.then(function(response) {
callListService('getArticleTypelistById', 'Atid', 87, 10, '#LeftSideContent1', '#tmplLeftSideContent1', IDstoExclude);
});
}
function callService2() {
callListService('getArticleTypelistById', 'Atid', 87, 10, '#LeftSideContent1', '#tmplLeftSideContent1', IDstoExclude)
}
$.when(callService1()).then(callService2);
For this solution to work as you expect your code should look like something below:
function callService1(p1, p2, ...) {
return $.ajax(...)
.then(function(response) {
return something;
});
}
function callService2(something_from_s1) {
// work with something_from_s1 var
}
$.when(callService1(...)).then(callService2);
References:
http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/
http://api.jquery.com/category/deferred-object/
http://api.jquery.com/deferred.then/
Trying to understand prototypes. I'm playing around in Chrome's console and was hoping someone can point me to why this is happening.
function Gadget(name, color) {
this.name = name;
this.color = color;
this.whatAreYou = function(){
return 'I am a ' + this.color + ' ' + this.name;
}
}
Gadget.prototype.price = 100;
Gadget.prototype.rating = 3;
Gadget.prototype.getInfo = function() {
return 'Rating: ' + this.rating + ', price: ' + this.price;
};
var newtoy = new Gadget('webcam', 'black');
newtoy.constructor.prototype
Gadget {price: 100, rating: 3, getInfo: function} //Expected
Now if I try the following, prototype does not have the expected results.
function Gadget(name, color) {
this.name = name;
this.color = color;
this.whatAreYou = function(){
return 'I am a ' + this.color + ' ' + this.name;
}
}
Gadget.prototype = {
price: 100,
rating: 3,
getInfo: function() {
return 'Rating: ' + this.rating + ', price: ' + this.price;
}
};
var newtoy = new Gadget('webcam', 'black');
newtoy.constructor.prototype
Object {} //Empty Object!!!!!???
jsFiddle Demo
This is because you overwrote the prototype instead of extending it when you did this:
Gadget.prototype =
It is common when overwriting it, to make a facade of the constructor like this:
Gadget.prototype = {
constructor : Gadget
}
So for your exact situation:
Gadget.prototype = {
constructor : Gadget,
price: 100,
rating: 3,
getInfo: function() {
return 'Rating: ' + this.rating + ', price: ' + this.price;
}
};
Prototype is initially a special typed object. When you assign the prototype with a new object (the curly braces are short hand for a new object) you lose the special prototype object.
See How does JavaScript .prototype work? for a deeper explanation.