I have a code with 4 vars named Alex John Billy and Bob. I created an if-else statement and for now i only want the if statement to execute if ANY of the var's this.age value is found under 14 , and else statement if all vars are over 14
but right now only the else statement executes and i am assuming its because 2/4 vars have this.age value over 14. My question is how exactly can i consider all vars
function person(name, age){
this.name = name;
this.age = age;
}
var Alex = new person("Alex", 15);
var John = new person("John", 16);
var Billy = new person("Billy", 13);
var Bob = new person("Bob", 11);
if(this.age < 14){
document.write("oops!");
}
else{
document.write("yay!");
}
You could add your objects to an array and then check if at least one of the contained objects has an age lower than 14 using Array.prototype.some().
function person(name, age){
this.name = name;
this.age = age;
}
persons = [];
persons.push(new person("Alex", 15));
persons.push(new person("John", 16));
persons.push(new person("Billy", 13));
persons.push(new person("Bob", 11));
if(persons.some(p => p.age < 14)){
document.write("oops!");
}
else{
document.write("yay!");
}
You can push your person objects into another object, I've called it persons. Then you can loop through all the entries with a for of loop.
You can use Object.keys() to get an array of all the keys, or person objects in this case.
function person(name, age) {
this.name = name;
this.age = age;
}
const persons = {};
persons.Alex = new person("Alex", 15);
persons.John = new person("John", 16);
persons.Billy = new person("Billy", 13);
persons.Bob = new person("Bob", 11);
for (let pers of Object.keys(persons)) {
if (persons[pers].age < 14) {
console.log(persons[pers].name+": oops!");
} else {
console.log(persons[pers].name+": yay!");
}
}
EDIT:
As it transpires you only want one outcome for all the objects, this will change our code a little.
Now it's best to push() all the objects to an array, again, called persons then you can use every() to check each object against a function. If all the values pass you will get a TRUE but if one or more fail you will get a FALSE
function person(name, age) {
this.name = name;
this.age = age;
}
const persons = [];
persons.push(new person("Alex", 15));
persons.push(new person("John", 16));
persons.push(new person("Billy", 13));
persons.push(new person("Bob", 11));
if (persons.every(p => { p.age > 14 })) {
console.log('Yay!')
} else {
console.log('oops!')
}
Keeping the object:
If you want to keep the object for ease of use later we can make an array of all the ages using map()
function person(name, age) {
this.name = name;
this.age = age;
}
const persons = {};
persons.Alex = new person("Alex", 15);
persons.John = new person("John", 16);
persons.Billy = new person("Billy", 13);
persons.Bob = new person("Bob", 11);
if (!Object.keys(persons).map(k => {
return persons[k].age
}).some(e => e < 14)) {
console.log('Yay!');
} else {
console.log('oops!');
}
Create array for the 4person and use .map() to check them all like this example
function person(name, age) {
this.name = name;
this.age = age;
}
var Alex = new person("Alex", 15);
var John = new person("John", 16);
var Billy = new person("Billy", 13);
var Bob = new person("Bob", 11);
var persons = [Alex, John, Billy, Bob];
persons.map(prrson => {
if (prrson.age < 14) {
console.log("oops!");
} else {
console.log("yay!");
}
});
You have multiple possibilities so you want to create an array after we will check.
function person(name, age) {
this.name = name;
this.age = age;
}
var Alex = new person("Alex", 15);
var John = new person("John", 16);
var Billy = new person("Billy", 13);
var Bob = new person("Bob", 11);
var ages = [Alex.age, John.age, Billy.age, Bob.age];
for (i = 0; i < ages.length; i++) {
if (ages[i] < 14) {
document.write("oops!");
} else {
document.write("yay!");
}
}
Related
I've been trying to find a way to correctly define an array as one of the constructor values. Let's say we have a student and we need to have an array with his grades and then using the array we need to get an average from the student's grades. Sadly, I only found some threads addressing this in other programming languages. This is what I thought would work:
function student(name, surname, number, grades) {
this.name = name;
this.surname = surname;
this.number = number;
this.grades = [];
this.average = function(grades) {
var sum = 0;
for(var i = 0; i < grades.length; i++) {
sum + = grades[i];}
var average = sum / grades.length;
return average;
}
}
And then
var student1 = new student("Peter","Cat",14444,[2,3,4]);
console.log(student1);
Unfortunately, it shows my grades array as blank and I can't see if my average function is working properly. Which part(s) should I change so that I would actually have some values in the grades array?
Thank you.
You have a couple things messed up. If you are going to pass the grades array in as an argument, then you need to set grades with this:
this.grades = grades;
Also in the average function you need to refer to grades with this.grades not just grades. This will allow you to add more grades later and still get the correct average. You could also consider making the grades optional by defining the constructor with something like:
function student(name, surname, number, grades =[])
Then if you don't pass in a value, an empty array will be waiting for you.
In the end you might have something like:
function student(name, surname, number, grades = []) {
this.name = name;
this.surname = surname;
this.number = number;
this.grades = grades;
this.average = function() {
return this.grades.reduce((a, c) => a + c, 0) / this.grades.length
}
}
var student1 = new student("Peter", "Cat", 14444, [2, 3, 4]);
console.log("Average: ", student1.average())
// add another grade:
student1.grades.push(6)
console.log("New Average: ", student1.average() )
You can solve same problem by using ES6, in your code, you are initializing this.grade=[] with an empty array inside function so further processing of average will be done on empty array only. For good practice, function parameters should be assigned with a default value, so that if mistakenly we do not pass an array as an argument then the function parameter will use the default value. Attaching code snippet for easy understanding in ES6.
class std{
constructor(name, surname, number, grades = []) {
this.name = name;
this.surname = surname;
this.number = number;
this.grades = grades;
}
average() {
if(this.grades.length !== 0){
return this.grades.reduce((previous, current) => previous + current, 0) /
this.grades.length
} else { return "no grades mentioned"; }
}
}
var student1 = new std("Peter", "Cat", 14444, [1, 3, 4]);
console.log("Average: ", student1.average());
//add new student
var student2 = new std("Prasanna", "sasne", 14444);
console.log(student2);
//student2.grades.push(7)
//console.log("New Average: ", student2.average() )
You're already passing grades into the student() function, so you don't need to pass it in to the student.average function (as the inner function will already have access to the outer function parameter). Because of this, you also don't need to set this.grades = [].
Also, sum + = grades[i] should be sum += grades[i].
Simply fixing this error, then omitting passing grades into the inner function will correctly show the average, as can be seen in the following:
function student(name, surname, number, grades) {
this.name = name;
this.surname = surname;
this.number = number;
this.average = function() {
var sum = 0;
for (var i = 0; i < grades.length; i++) {
sum += grades[i];
}
var average = sum / grades.length;
return average;
}
}
var student1 = new student("Peter", "Cat", 14444, [2, 3, 4]);
console.log(student1.average());
Your initialization of the variable is an empty array.
this.grades = [];
Should be
this.grades = grades;
However, I recommend that you study some javascript ES6 / ECMAScript 2015 and use classes.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes
class Student {
constructor(grades) {
//... Other code
this.grades = grades;
}
}
you can use this line :
function student(name, surname, number, grades){ }
instead of this:
function student(name, surname, number, grades = [ ]){ }
function student(name, surname, number, grades) {
this.name = name;
this.surname = surname;
this.number = number;
this.grades = grades;
this.average = function() {
return this.grades.reduce((a, c) => a + c, 0) / this.grades.length
}
}
var student1 = new student("Peter", "Cat", 14444, [2, 3, 4]);
console.log("Average: ", student1.average())
// add another grade:
student1.grades.push(6)
console.log("New Average: ", student1.average() )
We can use the Object Method to store the Average value:
function Student(name, surname, number, grades = [])
{
this.name = name;
this.surname = surname;
this.number = number;
this.grades = grades;
//Method to calculate the Average
this.average = function()
{
if(this.grades.length !==0)
{
//Return the Average Calculation
return this.grades.reduce((previous, current) => previous + current, 0) / this.grades.length
}
else
{
//This will return if grades not provided
return "No Grades Mentioned"
}
}
}
//With Grades
var student1 = new Student("Srinivasan", "Raja", 1635, [22,43,67,89,90]);
console.log(student1, "Average: "+ student1.average());
//Without Grades
var student1 = new Student("Denny", "Lawrence", 1635);
console.log(student1, "Average: "+ student1.average());
I have the following js functions:
function Weekday (name, traffic) {
this.name = name;
this.traffic = traffic;
}
function mostDays(){
var traffic=[];
traffic[0] = new Weekday('monday',6);
traffic[1] = new Weekday('tuesday',5);
return traffic;
}
function mostPopularDays(week) {
if(week.length == 0 || week === null) return null;
return Math.max.apply(Math, week['traffic']);
}
so if I say:
var x = mostDays();
var test = mostPopularDays(x);
I'm trying to get back 6 which is the max value of traffic amongst the Weekday objects . Is there a way to reference this correctly or do I need to do all this in a loop?
You could map the wanted property of the object and get then the max value.
function Weekday(name, traffic) {
this.name = name;
this.traffic = traffic;
}
function mostDays() {
var traffic = [];
traffic[0] = new Weekday('monday', 6);
traffic[1] = new Weekday('tuesday', 5);
return traffic;
}
function mostPopularDays(week) {
if (!week.length) return null;
return Math.max.apply(Math, week.map(function (o) { return o.traffic; }));
}
var x = mostDays();
var test = mostPopularDays(x);
console.log(test);
With ES6, you could spread the values for Math.max.
function Weekday(name, traffic) {
this.name = name;
this.traffic = traffic;
}
function mostDays() {
return [
new Weekday('monday', 6),
new Weekday('tuesday', 5)
];
}
function mostPopularDays(week) {
if (!week.length) return null;
return Math.max(...week.map(o => o.traffic));
}
var x = mostDays();
var test = mostPopularDays(x);
console.log(test);
If you want to return the day for which traffic is the most then Math.max cannot do it on its own, as it will just return the highest traffic (if you code it right), but not the day.
You could use find to do the lookup of the day with the highest traffic:
var maxTraffic = Math.max(...week.map(day => day.traffic));
return week.find(day => day.traffic === maxTraffic);
Another option can be to specify the default valueOf of the object:
function Weekday(name, traffic) {
this.name = name;
this.traffic = traffic;
}
Weekday.prototype.valueOf = function() { return this.traffic }
var days = [ new Weekday('monday', 6), new Weekday('tuesday', 5) ]
console.log( Math.max.apply(0, days) )
console.log( Math.max(...days) )
Otherwise, reduce can be used:
function Weekday(name, traffic) {
this.name = name;
this.traffic = traffic;
}
var days = [ new Weekday('monday', 6), new Weekday('tuesday', 5) ]
var max = days.reduce((m, d) => Math.max(m, d.traffic), 0)
console.log(max )
In the below code I am trying to print out just the first value (name) of the array, but it doesn't work as I expect:
function Person (name, age) {
this.name = name;
this.age = age;
}// Our Person constructor
// Now we can make an array of people
var family = new Array();
family[0] = new Person("alice", 40);
family[1] = new Person("bob", 42);
family[2] = new Person("michelle", 8);
family[3] = new Person("timmy", 6);
// loop through our new array
for(i = 0; i <= family.Length; i++) {
console.log( family[i].this.name);
}
You are using the "this" keyword incorrectly. When you access family[i] you are already accessing an instance of that prototype in JavaScript. Just drop the "this."
To get the first item from the array you could do the below without the loop:
console.log(family[0].name);
Without looping, as the loop is unnecessary if you know which item you want to print.
Or, if the loop is necessary you could add some logic such as
if(i === 0) {
console.log(family[0].name);
}
You do not need to use this when accessing the name property of the object in the array.
function Person (name, age) {
this.name = name;
this.age = age;
}// Our Person constructor
// Now we can make an array of people
var family = new Array();
family[0] = new Person("alice", 40);
family[1] = new Person("bob", 42);
family[2] = new Person("michelle", 8);
family[3] = new Person("timmy", 6);
// loop through our new array
for(i = 0; i < family.length; i++) {
console.log( family[i].name);
}
I am working on a Person constructor function that takes a name and age as its parameters, and trying to implement a method that retrieves all the 'Person' instances current age value and outputs the average. Here's my code...
var Person = (function() {
//private state
var inst = 1;
function Person(name, age) {
this.name = name;
this.age = age;
Object.defineProperty(this, "age", {
get: function() {
return age;
},
set: function(num) {
age = num;
}
});
Object.defineProperty(this, "_id", {
value: inst++
});
}
//Attempt to return number of instances divided by all current Person weights
Person.prototype.aveAge = function() {
return inst;
};
return Person;
}());
var jim = new Person("jim", 32);
var richard = new Person("richard", 27);
richard.age = 28;
var alfie = new Person("alfie", 42);
Person.aveAge() //Returns TypeError: Person.aveAge is not a function
I have set up a variable that is shared across all instances (inst) that increments each time an another instance is created and assigns a unique id. I cannot figure out how I can get to each 'age' value of all Person instances in existence using the aveAge prototype I have added at the bottom. I am also getting a 'TypeError: Person.aveAge is not a function' when I attempt to call it to even test that variable 'inst' holds the correct number of instances. Does anybody know where I am going wrong?
It feels strange to keep ages on a person when it references people. Notice that hanging things on __proto__ makes them available from the constructor (Person), while hanging things on prototype makes them available from the instance (richard). If Age is updated, it needs to be done via setAge so the PeopleTracker knows to update it's memory. Also, in my example, the average is only calculated when needed rather than each time a person wants to know what is is.
var peopleTracker = {
_count: 0,
_ages: [],
averageAge: 0,
addPerson: function (age) {
var pt = peopleTracker;
pt._count += 1;
pt._ages.push(age);
pt.getAverage();
},
getAverage: function () {
var sum = 0,
pt = peopleTracker;
sum = pt._ages.reduce(function (a, b) {
return a + b;
});
pt.averageAge = Math.round(sum / pt._count);
},
update: function (oldAge, newAge) {
var pt = peopleTracker,
ages = pt._ages,
i = ages.indexOf(oldAge);
ages.splice(i, 1, newAge);
pt.getAverage();
}
};
var Person = function (name, age) {
this.name = name;
this.age = age;
peopleTracker.addPerson(age);
};
Person.__proto__ = { // available from the constructor
Constructor: Person,
setAge: function (age) {
var oldAge = this.age;
this.age = age;
peopleTracker.update(oldAge, age);
},
aveAge: function () {
return peopleTracker.averageAge;
}
};
Person.prototype = Person.__proto__; // now also available from the instance
var jim = new Person("Jim", 32),
richard = new Person("Richard", 27),
alfie = new Person("Alfie", 42);
Person.aveAge(); // 34
richard.aveAge(); // 34
richard.setAge(20);
Person.aveAge(); // 31
richard.aveAge(); // 31
I learned there are 2 types of creating objects. First: object literal notation and second: Object constructor. I have learned that there are also methods and functions, but I couldn't understand how to create a method in object literal notation? In object constructor I just write:
var bob = new Object();
bob.age = 30;
bob.setAge = function(newAge) {
bob.age = newAge;
};
Can you please tell me how to do the same when writing object literal notation.
var bob = {
age: 30
};
Syntactically, the change is very simple :
var bob = {
age: 30,
setAge: function (newAge) {
bob.age = newAge;
}
};
But as you can see, there's a problem : as in your code it uses the external bob variable so this wouldn't work if you change the value of the bob variable.
You can fix that with
var bob = {
age: 30,
setAge: function (newAge) {
this.age = newAge;
}
};
Note that at this point you should check whether what you need isn't, in fact, a class, which would bring some performance improvements if you have several instances.
Update: ECMAScript 6 now allows methods to be defined the same way regardless of whether they are in an object literal:
var bob = {
age: 30,
setAge (newAge) {
this.age = newAge;
}
};
Its nothing different and as easy as
var bob = {
age: 30,
setAge: function( newAge ) {
this.age = newAge;
}
};
Alternatively, you can create a real setter function either by invoking Object.defineProperty() or as simple as
var bob = {
age: 30,
firstName: 'j',
lastName: 'Andy',
set setName( newName ) {
var spl = newName.split( /\s+/ );
this.firstName = spl[ 0 ];
this.lastName = spl[ 1 ];
}
}
Where you could go like
bob.setName = "Thomas Cook"; // which sets firstName to "Thomas" and lastName to "Cook"
The last code you posted is missing a comma. Also, you don't need a ';' after a function definition of an object's property. Like this:
var object2 = {
name: "Fred",
age: 28,
club: "Fluminense",
bio2: function (){
console.log(this.name +" is "+ this.age + " years old and he is playing in "+ this.club);
}
};
This is the way to solve this exercise using literal object creation method:
var setAge = function (newAge) {
this.age = newAge;
};
var bob = new Object();
bob.age = 30;
bob.setAge = setAge;
var susan = {
age: 25,
setAge: setAge
}
susan.setAge(35);
If you want encapsulation, you might use the following syntax(self-executing function). Here age is not accessible from the outside of the object bob.
var bob = (function() {
//...private
var age = 30;
function setAge(newAge) {
age = newAge;
};
function getAge() {
return age;
}
// Public api
return {
setAge: setAge,
getAge: getAge
}
}());
bob.setAge(50);
alert(bob.getAge());
jsfiddle: http://jsfiddle.net/61o9k98h/1/
Starting with ECMAScript 2015, a shorter syntax for method definitions on objects initializers is introduced. It is a shorthand for a function assigned to the method's name
const bob = {
age: 30,
setAge(age) {
this.age = age;
},
};
alert(bob.age); // 30
bob.setAge(63); // set age = 63
alert(bob.age); // 63
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Method_definitions
Like this:
var bob = {
age: 30,
setAge: function (age) {
this.age = age;
}
}
alert(bob.age); // 30
bob.setAge(45); // set age = 45
alert(bob.age); // 45