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
Related
let construct = function(name = "john", last = "marks") {
return {
name: name,
last: last,
};
};
let me = new construct("mike", "tyson");
console.log(me);
You do not have a constructor function.
A constructor function is one you can call with the keyword new in order to produce a new instance of said function. However, yours that just produces plain objects with no inheritance:
Your implementation:
let construct = function(name = "john", last = "marks") {
return {
name: name,
last: last,
};
};
let me = new construct("mike", "tyson");
console.log(me instanceof construct); //false
Proper constructor function:
let construct = function(name = "john", last = "marks") {
this.name = name;
this.last = last;
};
let me = new construct("mike", "tyson");
console.log(me instanceof construct); //true
This matters if you want to use prototypal inheritance for the produced instances:
let construct = function(name = "john", last = "marks") {
this.name = name;
this.last = last;
};
let me = new construct("mike", "tyson");
construct.prototype.fullName = function() {
return `${this.name} ${this.last}`;
}
console.log(me.fullName()); //"mike tyson"
In order to produce proper instances with new, it needs to either return nothing (which implicitly produces undefined) or return anything other than an object:
function example() {
this.foo = "bar";
return "this is not an object";
}
console.log(example());
console.log(new example());
I am new to JavaScript. And I want to make sense of a feature in JavaScript. Please consider the following example:
function Dog(name) {
this.name = name
}
Dog.prototype.bark = function() {
console.log(this.name +" :Hello, human.");
}
var max = new Dog("Max", "Buddy")
max.bark();
As you can see two arguments were passed into making a new dog object while only one (name) was required.
I know that the second argument is unused, but where is it stored/ is there any utility to passing an extra argument?
Thank you in advance!
They can be retrieved in the arguments object:
arguments is an Array-like object accessible inside functions that
contains the values of the arguments passed to that function.
function Dog(name) {
console.log(arguments);
this.name = name;
}
Dog.prototype.bark = function() {
console.log(this.name +" :Hello, human.");
}
var max = new Dog("Max", "Buddy");
max.bark();
The modern alternative would be the spread operator:
function Dog(...names) {
console.log(names);
}
var max = new Dog("Max", "Buddy");
They are store in arguments array :
function Dog(name) {
this.name = name
console.log(arguments)
}
Dog.prototype.bark = function() {
console.log(this.name +" :Hello, human.");
}
var max = new Dog("Max", "Buddy", "Arm", {name: "Jacob"})
max.bark();
if you are not using js in strict mode you can access the arguments property of function.
function Dog(name) {
this.name = name
// all the arguments are inside arguments property of function
console.log(arguments);
}
Dog.prototype.bark = function() {
console.log(this.name +" :Hello, human.");
}
var max = new Dog("Max", "Buddy")
max.bark();
Javascript is a dynamic language. Same function can accept dynamic arguments. There are multiple way to access all variable passed 2 a function/constructor.
Using arguments.
Using vaargs or rest operator.
Mix of rest operator and arguments.
It depends how you want to use the values. See the below examples.
function DogArgs(name) {
this.name = name;
console.log(arguments); // array like structure [Arguments] { '0': 'Max', '1': 'Buddy' }
}
function DogRest(...names) {
this.name = names[0];
console.log(names); // Array [ 'Max', 'Buddy' ]
}
function DogPartialRest(name, ...others) {
this.name = name;
console.log(others); // Array [ 'Buddy' ]
}
var max1 = new DogArgs("Max", "Buddy");
var max2 = new DogRest("Max", "Buddy");
var max3 = new DogPartialRest("Max", "Buddy");
Example 1: Using arguments
function sum() {
const values = Array.from(arguments); // convertin array, since arguments is not array
return values.reduce((sum, val) => (sum += val), 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4)); // 10
Example 2: Using vaargs or rest operator.
function sum(...values) {
return values.reduce((sum, val) => (sum += val), 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4)); // 10
Example 3: Mix of rest operator and arguments
function Person(name, age, ...rest) {
this.name = name
this.age = age
this.salary = 0
if(rest.length) {
this.salary = rest[0]
this.address = rest[1] || ''
}
}
console.log(new Person("deepak", 30)) // Person { name: 'deepak', age: 30, salary: 0 }
console.log(new Person("deepak", 30, 2000)) // Person { name: 'deepak', age: 30, salary: 2000, address: '' }
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!");
}
}
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
How can I achieve this?
var people = Array();
people.push({
name: "John",
height_in_cm : 190,
height_in_inches : this.height_in_cm * 0.39
});
This is not working. It's obvious that the object is not yet created. Are there any tricks on getting this to work?
You could just declare the object first and then push it:
var people = [];
var obj = {
name: "John",
height_in_cm : 190
};
obj.height_in_inches = obj.height_in_cm * .39;
people.push(obj);
Depending on your case you could also create a "Person" object/class:
var person = (function personModule() {
function Person(props) {
this.name = props.name;
this.height_in_cm = props.height_in_cm;
this.height_in_inches = this.height_in_cm * .39;
}
Person.prototype = {...}; // public methods if necessary
return function(props) {
return new Person(props);
}
}());
var people = [];
people.push(person({ name: 'John', height_in_cm: 190 }));
console.log(people[0].height_in_inches); //=> 74.1