I am getting unexpected output after setting the value of data member. What is the rationale behind this behavior?
function studentClass(id, name)
{
this.id = id;
this.name = name;
this.print = function() {
alert(id + ": " + name);
}
}
var s = new studentClass(101, "Vijay");
s.print(); // 101, Vijay
alert(s.id); // 101
alert(s.name); // Vijay
s.id = 102;
alert(s.id); // 102
s.print(); // 101, Vijay Why?
https://jsfiddle.net/00d1cvxL/5/
You should be using alert(this.id + ": " + this.name); in the print function.
Earlier it was displaying the arguments id and name that you passed to studentClass.
Related
I understand the part upto the object 'Character' being made. But when we make a prototype object 'Player', i dont get concept behind this
Player.initPlayer = function(name, health, force){......}
What is this '.initPlayer' ?
And this function without any name, is their any alternative for definig this function ?
Like that there are more functions without any name and are just assigned to Player's object like - Player.describe=function(), What is 'fight' in this line ?
The actual code is at the bottom of the page of this link: https://openclassrooms.com/courses/learn-the-basics-of-javascript/understand-object-oriented-programming
Under the last topic of this page, Under the heading: 'Next Level:make a game!'
I will also copy the code here.
var Character = {
// Initialize the character
initCharacter: function (name, health, force) {
this.name = name;
this.health = health;
this.force = force;
},
// Attack a target
attack: function (target) {
if (this.health > 0) {
var damage = this.force;
console.log(this.name + " attacks " + target.name + " and causes " + damage + " damage points");
target.health = target.health - damage;
if (target.health > 0) {
console.log(target.name + " has " + target.health + " health points left");
} else {
target.health = 0;
console.log(target.name + " has been eliminated!");
}
} else {
console.log(this.name + " can't attack (they've been eliminated).");
}
}
};
var Player = Object.create(Character);
// Initialize the player
Player.initPlayer = function (name, health, force) {
this.initCharacter(name, health, force);
this.xp = 0;
};
// Describe the player
Player.describe = function () {
var description = this.name + " has " + this.health + " health points, " +
this.force + " force points " + this.xp + " experience points";
return description;
};
// Fight an enemy
Player.fight = function (enemy) {
this.attack(enemy);
if (enemy.health === 0) {
console.log(this.name + " eliminated " + enemy.name + " and wins " +
enemy.value + " experience points");
this.xp += enemy.value;
}
};
var Enemy = Object.create(Character);
// Initialize the enemy
Enemy.initEnemy = function (name, health, force, species, value) {
this.initCharacter(name, health, force);
this.species = species;
this.value = value;
};
// ...
Then the method calls for running the above code
// ...
var player1 = Object.create(Player);
player1.initPlayer("Rainbow Dash", 150, 25);
var player2 = Object.create(Player);
player2.initPlayer("Applejack", 130, 30);
console.log("Welcome to the adventure! Here are our heros:");
console.log(player1.describe());
console.log(player2.describe());
var monster = Object.create(Enemy);
monster.initEnemy("Spike", 40, 20, "orc", 10);
console.log("A wild monster has appeared: it's a(n) " + monster.species + " named " + monster.name);
monster.attack(player1);
monster.attack(player2);
player1.fight(monster);
player2.fight(monster);
console.log(player1.describe());
console.log(player2.describe());
Please explain. I do get the argument passing and catching. I just dont understand the construct.
So basically what the line Player.initPlayer = function(name, health, force){......} is doing is declaring the function method initPlayer() for each Player object that will be created.
It is (mostly) the same as saying
var Player = {
initPlayer: function(params) {function here}
}
except it is declared as part of the constructor function for Player, so each Player object created using the new keyword will have access to it.
If this syntax is not clear to you, read up on constructor functions and the different way to declare and create objects in JS. Here is a good place to start.
This question already has answers here:
How do JavaScript closures work?
(86 answers)
Closed 6 years ago.
I am having problem identifying what and how is some property of "local" scope in JS. How is the property _secretNum "private" when it is clearly available outside the scope of the constructor as per below line.
document.write("Value of secretNum in secret: " + secret._secretNum
+ "<br/>");
The full code is as below,
<body>
<script type="text/javascript">
function SecretCode() {
var _secretNum = 78;
this.guessNum = function(num) {
if (num > _secretNum) {
return "Lower";
} else if (num < _secretNum) {
return "Higher";
} else {
return "You guessed it";
}
}
this.setNum = function(newNum) {
this._secretNum = newNum;
}
this.getNum = function() {
return this._secretNum;
}
}
var secret = new SecretCode();
for ( var prop in secret) {
document.write(prop + " : " + secret[prop] + "<br/>");
}
document.write("Is 70 the number: " + secret.guessNum(70) + "<br/>");
secret.setNum(9);
document.write("Value of secretNum in secret: " + secret.getNum()
+ "<br/>");
document.write("Value of secretNum in secret: " + secret._secretNum
+ "<br/>");
var secretAliter = new SecretCode();
secretAliter.setNum(17);
document.write("Value of secretNum in secretAliter : "
+ secretAliter.getNum() + "<br/>");
document.write("Value of secretNum in secretAliter : "
+ secretAliter._secretNum + "<br/>");
</script>
</body>
How is the property _secretNum "private"
It's not, I don't know where you got that code from, but it's broken.
The local variable declared by var _secretNum = 78 is private, but it's also being ignored by the setNum and getNum accessor methods. They're using this._secretNum, which is a completely different not private variable, that has nothing to do with the var _secretNum = 78 line. You can change the value of this._secretNum all you want, both directly and by using setNum, and it won't affect the variable _secretNum which guessNum uses.
The point of declaring var _secretNum as a local variable within your constructor function is that it is only accessible within that function, and by the functions that "close over" it when they are returned. Drop the this._secretNum from your accessors and just use _secretNum.
By way of example:
function MyConstructor() {
var _name = "bob" // Completely private
this._age = 45 // Not private
this.getName = function () {
return _name // public accessor for private variable
}
this.getAge = function() {
return this._age // public accessor for public property
}
}
var x = new MyConstructor();
x._name = "blah" // unrelated, ignored by getName
alert(x.getName()) // bob, not "blah"
x._age = 25 // overwrite age
alert(x.getAge()) // 25
I was wondering how can I make it posible to get rid of putting "new" before a function, for example:
new functionToDo("thingsToDo").iGotYouBruh("Halo Humans");
is there a posible way of doing this without the "new"?
here is the code I'm trying to use without the "new":
function local (title) {
var storeTitle = title;
this.addL = function(lString) {
var storeText = lString;
localStorage.setItem(storeTitle, storeText);
console.info("Locally stored " + storeTitle.toUpperCase() + " with " + storeText.substring(0, 10) + "... As text.");
};
this.removeL = function() {
localStorage.removeItem(storeTitle);
console.info("Locally removed " + storeTitle + ".");
};
this.getL = function () {
localStorage.getItem(storeTitle);
console.info("Locally got string of " + storeTitle + ": " + localStorage.getItem(storeTitle));
};
};
and here's what I would have to do to invoke the function:
new local("storedElement").getL();
This is possible by checking whether this is an instance of the function itself and returning a new instance otherwise:
function local (title) {
if (!(this instanceof local)) {
return new local(title);
}
var storeTitle = title;
this.addL = function(lString) {
var storeText = lString;
localStorage.setItem(storeTitle, storeText);
console.info("Locally stored " + storeTitle.toUpperCase() + " with " + storeText.substring(0, 10) + "... As text.");
};
this.removeL = function() {
localStorage.removeItem(storeTitle);
console.info("Locally removed " + storeTitle + ".");
};
this.getL = function () {
localStorage.getItem(storeTitle);
console.info("Locally got string of " + storeTitle + ": " + localStorage.getItem(storeTitle));
};
};
You could use JavaScript closures. In particular look at the "Using Closures for the Module Pattern" section of this webpage for a full description. The idea is to have the function return an literal with all the required methods. Any functions or variables that you want to be kept private are just local variables for the function.
I've been programming for over 20 years, but have recently turned to JavaScript. Despite spending hours trawling the web, the penny hasn't yet dropped with the prototype inheritance method.
In the simplified code below, I am trying to inherit the 'name' property from the Synthesizer 'class' to the Roland 'class', but the only way I seem to be able to access it is by using 'Synth2.prototype.name' rather than by 'Synth2.name' (which returns undefined). I would like to get the approach working so that I can use 'Synth2.name', as portability is a design requirement.
I would be very grateful for any assistance.
function Synthesizer(name) {
this.name = name;
}
function Roland(name) {
this.prototype = new Synthesizer(name);
}
Synth1 = new Synthesizer("Analogue");
Synth2 = new Roland("Fantom G6");
document.write(Synth1.name + '<br>');
document.write(Synth2.name + '<br>');
Thanks guys! (Now updated with call to super class)...
function Synthesizer(name) {
this.name = name;
this.rendersound = function () {
document.write("applying envelope to " + this.name + "<br>");
}
}
function Roland(name) {
Synthesizer.call(this, name);
this.prototype = Synthesizer;
this.Synthesizer_rendersound = this.rendersound;
this.rendersound = function () {
document.write("applying differential interpolation to " + this.name + "<br>");
this.Synthesizer_rendersound(this);
}
}
Synth1 = new Synthesizer("Analogue");
Synth2 = new Roland("Fantom G6");
document.write(Synth1.name + '<br>');
document.write(Synth2.name + '<br>');
document.write('<br>');
Synth1.rendersound();
document.write('<br>');
Synth2.rendersound();
document.write('<br>');
document.write('Synth1.prototype ' + Synth1.prototype + '<br>');
document.write('Synth2.prototype ' + Synth2.prototype + '<br>');
document.write('<br>');
document.write('Synth1.constructor ' + Synth1.constructor + '<br>');
document.write('Synth2.constructor ' + Synth2.constructor + '<br>');
You can do this by several way.
For example :
var Synthesizer = function(name){
this.name = name;
}
function Roland(name) {
Synthesizer.call(this, name); // you call the constructor of Synthesizer
// and force Synthesizer's this to be Roland's this
}
function clone(obj){
var ret = {};
for(var i in obj){ ret[i] = obj[i]; }
return ret;
}
Roland.prototype = clone(Synthesizer.prototype); // inheritance of public functions
For Function.prototype.call : https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/Call
I believe you have to set the constructor's prototype, like this:
function Synthesizer(name) {
this.name = name;
}
function Roland(name) {
this.name = name;
}
Roland.prototype = new Synthesizer();
Synth1 = new Synthesizer("Analogue");
Synth2 = new Roland("Fantom G6");
document.write(Synth1.name + '<br>');
document.write(Synth2.name + '<br>');
Note: No jQuery
How could i do something like this:
var array = new Array();
array[name] = "Tom";
array[age] = 15;
foreach(array as key=>value){
alert(key + " = " + value);
}
First of all, you should call it obj or person instead of array; an array is a sequence of similar elements, not a single object.
You can do it like this:
var person = new Object();
person['name'] = "Tom";
person['age'] = 15;
for (var key in person) {
if(!person.hasOwnProperty(key)) continue; //Skip base props like toString
alert(key + " = " + person[key]);
}
You can also initialize the object using properties, like this:
person.name = "Tom";
person.age = 15;
You can also use JavaScript object literal syntax:
var person = { name: "Tom", age: 15 };
This will work in your simple example scenario:
for (var key in array) {
alert(key + " = " + array[key]);
}
For general use, it's recommended that you test to be sure that the property hasn't been grafted onto the object somewhere else in the inheritance chain:
for (var key in array) {
if (array.hasOwnProperty(key)) {
alert(key + " = " + array[key]);
}
}
Use a javascript object
var object = {};
object.name = "Tom";
object.age = 15;
for ( var i in object ) {
console.log(i+' = '+ object[i]);
}
First, you don't want an array, you want an object. PHP's idea of what constitutes an array is frankly a little weird.
var stuff = {
name: "Tom",
age: 15
};
/* Note: you could also have done
var stuff = {};
stuff.name = "Tom";
stuff.age = 15;
// or
var stuff = {};
stuff["name"] = "Tom";
stuff["age"] = 15;
*/
for (var key in stuff) {
alert(key + " = " + stuff[key];
}
key=0;while(key<array.length) {
alert(key + " = " + array.item(key));
key++;
}