Make Unique Objects by Passing Parameters to our Constructor:
The constructor we have is great, but what if we don't always want to create the same object?
To solve this we can add parameters to our constructor. We do this like the following example:
var Car = function(wheels, seats, engines) {
this.wheels = wheels;
this.seats = seats;
this.engines = engines;
};
Now we can pass in arguments when we call our constructor.
var myCar = new Car(6, 3, 1);
This code will create an object that uses the arguments we passed in and looks like:
{
wheels: 6,
seats: 3,
engines: 1
}
Now give it a try yourself! Alter the Car constructor to use parameters to assign values to the wheels, seats, and engines properties.
Then call your new constructor with three number arguments and assign it to myCar to see it in action.
Please complete the code given below :
var Car = function() {
//Change this constructor
this.wheels = 4;
this.seats = 1;
this.engines = 1;
};
//Try it out here
var myCar;
Instructions :
Calling new Car(3,1,2) should produce an object with a wheels
property of 3, a seats property of 1, and an engines property of 2.
Calling new Car(4,4,2) should produce an object with a wheels
property of 4, a seats property of 4, and an engines property of 2.
Calling new Car(2,6,3) should produce an object with a wheels
property of 2, a seats property of 6, and an engines property of 3.
myCar should have number values for the wheels, seats, and engines
properties.
My attempt :
var Car = function() {
//Change this constructor
this.wheels = 4;
this.seats = 1;
this.engines = 1;
};
//Try it out here
var myCar = function(wheels, seats, engines) {
this.wheels = wheels;
this.seats = seats;
this.engines = engines;
};
var myCar = new Car(6, 3, 1);
Coding challenge answer for the link you added will be :
var Car = function(wheels, seats, engines) {
if(isNaN(wheels))
wheels = 0;
if(isNaN(seats))
seats = 0;
if(isNaN(engines))
engines = 0;
this.wheels = wheels;
this.seats = seats;
this.engines = engines;
};
//Try it out here
var myCar = new Car(2,6,3);
myCar = new Car(3,1,2);
myCar = new Car(4,4,2);
Run tests after adding this code. - all will pass
You answered already yourself:
var Car = function(wheels, seats, engines) {
//additional checks
if(isNaN(wheels))
wheels = 0;
if(isNaN(seats))
seats = 0;
if(isNaN(engines))
engines = 0;
this.wheels = wheels;
this.seats = seats;
this.engines = engines;
};
//Try it out here
var myCar = new Car(3,1,2);
console.dir(myCar);
myCar = new Car(4,4,2);
console.dir(myCar);
myCar = new Car(2,6,3);
console.dir(myCar);
Related
I want to create an instance of the object Player, which as an instance of the object Weapon nested in it.
For example, player1 should start the game with a dagger.
I tried different things but the nested object (weapon) is not in the player instance.
function Weapon(name, damage) {
this.name = name;
this.damage = damage;
}
function Player(name, life) {
this.name = name;
this.life = life;
this.weapon = {
name: name,
damage: damage
};
}
const player1 = new Player("Joueur 1", 100, dagger);
const dagger = new Weapon("Dague", 5);
const sword = new Weapon("Epée", 10);
const axe = new Weapon("Hache", 15);
const flail = new Weapon("Fléau", 20);
What is the right syntax to add this weapon as a nested object?
Also, the weapon may change during the game.
I think you're looking for something like this, you're currently trying to pass a parameter but the constructor isn't expecting it. I've given 2 examples of how you could achieve this.
function Weapon(name, damage) {
this.name = name;
this.damage = damage;
}
function Player(name, life, weapon) {
this.name = name;
this.life = life;
this.weapon = weapon;
}
const dagger = new Weapon("Dague", 5);
const player1 = new Player("Joueur 1", 100, dagger);
const player2 = new Player("Joueur 1", 100, new Weapon("Dague", 5));
console.log(player1);
console.log(player2);
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 try to access an object which is global; it's a kind of a preset.
var perks = {health: 100, attack: 10};
var player = function(hp) {
this.stats = perks;
//Changing some standard values..
this.stats["health"] = hp;
}
var Peter = new player(200);
var Steven = new player(300);
I hope you get my intention; the problem is, that it won't work correct, and I'm not even sure what it does wrong. If I create more than one player, e.g. Steven, Collin and James, every player has the same perks. In this example Peter and Steven both have 300 health.
If I change the line
this.stats = perks;
to
this.stats = {health: 100, attack: 10};
everything works like intended. Peter and Steven both have their own stats.
How do I access the global var perks?
It happens because in JavaScript object does not copy that way, thats why all of your players using the same perks object.
There is a few ways to solve it:
Create new object with a function (object own constructor).
function createPerks() {
return {
health: 100,
attack: 10
};
}
var player = function(hp) {
this.stats = createPerks();
//Changing some standard values..
this.stats["health"] = hp;
}
var Peter = new player(200);
var Steven = new player(300);
Create new object each time and use constants for default values:
var BASE_HEALTH = 100;
var BASE_ATTACK = 10;
var player = function(hp) {
this.stats = {
health: BASE_HEALTH,
attack: BASE_ATTACK
};
//Changing some standard values..
this.stats["health"] = hp;
}
var Peter = new player(200);
var Steven = new player(300);
Use Object.create (works in IE9+, but shimable for older browsers):
var perks = {health: 100, attack: 10};
var player = function(hp) {
this.stats = Object.create(perks);
//Changing some standard values..
this.stats["health"] = hp;
}
var Peter = new player(200);
var Steven = new player(300);
Keep in mind that Object.create does not clone an object but inherit one object from another.
Object.create shim for old browsers by Douglas Crockford:
if (typeof Object.create !== 'function') {
Object.create = function (o) {
function F() {}
F.prototype = o;
return new F();
};
}
The moment you write this.stats = perks; both of them refer to the same object that is {health: 100, attack: 10}. So any changes made to any one of them will always affect the other.
As var Steven = new player(300); is the last value you assigned. All your players will now have {health: 300, attack: 10}
I'm new to the prototype structure, and I'm having trouble figuring this one out. Here's my JavaScript code.
var Game = function ()
{
//some variables
};
Game.prototype.block =
{
spawn: function () {
var t1 = new this.inst;
},
inst : {
x: 5,
y: 0,
type: ''
}
};
When I try to create a new object "inst" I get the following error:
TypeError: object is not a function. What am I doing incorrectly?
If you want to create objects that inherit from the inst object, you can do that using Object.create, with var t1 = Object.create(this.inst);.
var Game = function () {
//some variables
};
Game.prototype.block = {
spawn: function () {
var t1 = Object.create(this.inst);
},
inst : {
x: 5,
y: 0,
type: ''
}
};
So then your code would look something like this;
var game = new Game();
game.block.spawn();
And the .spawn() method would have a variable that references an object that inherits from the Game.prototype.block.inst object.
First of all, inst is not defined within the scope of Game. So, this which refers to Game doesn't have any properties called inst. Secondly, inst must be followed by () to indicate a call to the constructor, which you are missing here.
I guest you need a static factory method to create new "inst". is the below code what you need? you call the Game.spawn method to generate a new inst, and you can put this method in setInterval.
function Game() {
//some variables
}
Game.spawn = function() {
function Inst() {
this.x = 5;
this.y = 0;
this.type = '';
}
return new Inst;
}
var inst1 = Game.spawn();
inst1.x = 1; //test inst1
console.log(inst1.x);
var inst2 = Game.spawn();
inst2.x = 2; //test inst2
console.log(inst2.x);
var inst3 = Game.spawn();
inst3.x = 3; //test inst 3
console.log(inst3.x);