loop throught a function properties, possible? - javascript

I want to loop through a functions properties, here is my attempt:
var hen = function a() {
this.name = "euler henrique";
this.ID = 55530;
this.REC = 0302;
this.nick = "any will do";
}
for (var p in hen) {
console.log(hen[p]);
}
but that doesn't work, even if hen was an instance of a. Any suggestion?

A quick solution might be to add the elements to an array, as a property of the parent object. For instance
var hen = function a() {
this.name = "euler henrique";
this.ID = 55530;
this.REC = 0302;
this.nick = "any will do";
this.info = [this.name, this.id, this.REC, this.nick];
}
And then looping through this array the way you would any array.
var myHen = new Hen();
for(var x = 0; x < myHen.info; x ++)
{
info = myHen.info[x];
if(info)
{
console.log(info);
}
}
Not sure if this what you were going for, let me know if this isn't what you need and i'd be happy to share some other ideas.

You can do it if you create an instance of the object:
var Hen = function() {
this.name = "euler henrique";
this.ID = 55530;
this.REC = 0302;
this.nick = "any will do";
}
var myHen = new Hen();
for (let prop in myHen) {
if (myHen.hasOwnProperty(prop)) {
console.log(prop);
}
}
You can create an object using the function constructor: new YourFunctionName();
From MDN: "The hasOwnProperty() method returns a boolean indicating whether the object has the specified property as its own property (as opposed to inheriting it)."

Related

How can I calculate variable in constructor using another variable in this constructor function

class CreateNewWord {
constructor(id, title, hold, droppedHere, bg) {
this.id = id;
this.title = title; <=== I want to use this variable
this.hold = hold;
this.droppedHere = droppedHere;
this.bg = bg;
this.letters = getLetter(title); <=== I want to make something like this
}
function getLetter(word) {
let letters = [];
for (let i = 0; i < word.length; i++) {
letters.push({
id: i + 1,
title: word[i],
hold: false,
droppedHere: false,
bg: "#a29bfe",
});
}
return letters;
}
}
So when I want to create an object I don't have to pass letters since it is created inside of the class
SOLUTION:
From
function getLetter(word) {...
To
getLetter(word) {... since I get and error if I use "function get..."
AND wrote this:
this.letters = this.getLetter(title);
thanks "ponury-kostek" for the help!

Accessing variables from a functionally declared stack

In creating the interface for a Stack in JavaScript - using a functional style as opposed to prototypal or pseudoclassical style, should the below "storage" and "count" variables be someInstance.storage and someInstance.count, respectively so they can be accessed on an instance of this stack later?
With the variables declared as they are now, once we create and instance of the stack by executing the function, we lose access to see what the count (size) and the storage (properties in the stack).
What's the best means of declaring properties (not methods) we need to access later using a functional creation pattern?
Thanks!
var Stack = function(){
var someInstance = {};
var storage = {};
var count = 0;
someInstance.push = function(value){
storage[count++] = value;
};
someInstance.pop = function(){
if(count){
var popped = storage[--count];
}
delete storage[count];
return popped;
};
someInstance.size = function(){
return count;
};
return someInstance;
};
var stack = Stack();
The private variables mentioned below can be studied in javascript of closure.
reference: https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures
var Stack = function(){
// PUBLIC
var someInstance = {};
// PRIVATE: Attach _ to private variables. (just implicit rule.)
var _storage = {};
var _count = 0;
someInstance.push = function(value){
storage[_count++] = value;
};
someInstance.pop = function(){
if(_count){
var popped = storage[--_count];
}
delete storage[_count];
return popped;
};
someInstance._size = function(){
return _count;
};
// if you assign public variable, you can access!!!
someInstance.size = _size;
someInstance.count = _count;
return someInstance;
};
var stack = Stack();
You can add getters and setters for them in the someInstance object (courtesy of closures) like so:
Object.defineProperty(someInstance, "count", {
get: function() {
return count;
},
set: function(value) {
count = value;
}
});
You can omit the set part if you want to be able to just get the value and not set it.
Example:
var Stack = function(){
var someInstance = {};
var storage = {};
var count = 0;
Object.defineProperty(someInstance, "count", {
get: function() {
console.log("getter called");
return count;
},
set: function(value) {
console.log("setter called");
count = value;
}
});
return someInstance;
};
var stack = Stack();
console.log(stack.count);
stack.count = 55;
console.log(stack.count);
Whether storage and count should be someInstance.storage and someInstance.count depends on how you want the user of this instance to work it. That's a bit opinion based. My opinion is that a stack shouldn't allow the user to change the count with something like someInstance.count = 10 because that would break it.
Personally I would make count and storage private which will prevent accidental bugs that could happen with direct access. A nice way to do this is to capture them in a closure and provide a getter for count so you can still read the count, but can't change it. Something like:
var Stack = function(){
let storage = [], count = 0; // these will be caputured as a closure
return {
// the returned object will have push, pop, and a count getter
push(v) {
storage.push(v)
count++
},
pop() {
if (count) count--
return storage.pop()
},
get count(){ // allow reading of count
return count
}
}
}
var stack = Stack();
stack.push("hello");
stack.push("goodby");
stack.count = 10 // has no effect
console.log(stack.count) // count is still 2
console.log(stack.pop())
console.log(stack.count)
console.log(stack.pop())
console.log(stack.count)
Of course, since this mostly uses an array, you could do away with the count variable altogether and just use storage.length
var Stack = function(){
let storage = [], count = 0; // these will be caputured as a closure
return {
// the returned object will have push, pop, and a count getter
push(v) { //method
storage.push(v)
count++
},
pop: function() {
if (count) count--
return storage.pop()
},
get count(){ // allow reading of count
return count
},
get insidebox(){ // allow reading of count
return storage
},
callprice:function(cnt){
var price=cnt*100;
return price;
}
}
}
Stack.prototype.price2 = function() {
return "testpr";
};
var sb = Stack();
console.log(sb.count);
sb.push('paint');
console.log(sb.insidebox);
console.log(sb.count);
sb.push('Sharee');
console.log(sb.insidebox);
sb.push('Shirt');
sb.push('shoes');
console.log(sb.insidebox);
sb.pop();
console.log(sb.insidebox);
console.log(sb.count);
console.log(sb.callprice(sb.count));
function Person(first, last, age, eye) {
this.firstName = first;
this.lastName = last;
this.age = age;
this.eyeColor = eye;
}
Person.prototype.nationlity='Indian';
Person.prototype.fullname = function() {
return this.firstName + " " + this.lastName
};
var myFather = new Person("Lalji", "Maurya", 50, "blue");
console.log(myFather.fullname());
console.log(myFather);
console.log(myFather.nationlity);
var myBrother = new Person("Ashish", "Maurya", 28, "black");
console.log(myBrother.fullname());
console.log(myBrother);
console.log(myBrother.nationlity);

How to have function call its own function on its creation

I have a function PublicGame which I'd like to be using similar to a class. When I create PublicGame I give it a bunch of methods by setting this.methodName = function. The only thing is that I want to call some of these methods when the PublicGame is created. Right now for instance I do this.judge = this.setJudge(), but I know this wont work where I have it because, setJudge isnt defined yet. Should I put this at the bottom of PublicGame? Is my design totally off?
Code:
'use strict';
// var GameSockets = require(‘GameSockets’);
var Games = {};
var id_counter = 0;
var minPlayers = 3;
var maxPlayers = 6;
function PublicGame (players) {
this._id = id_counter++;
this.players = players;
this.gameSocket = new GameSockets.registerPlayers(this.players, this._id, this.playerDisconnects);
this.judge = this.setJudge();
this.killGame = function() {
delete Games[this._id];
};
// When a player presses leave game
this.playerExits = function(playerToRemove) {
// Delete player from players array
this.players.splice(this.players.indexOf(playerToRemove),1);
// If less than min players
if (this.players.length < minPlayers) this.killGame();
// If less than max players
if (this.players.length < maxPlayers) {
this.needsPlayers = true;
}
gameSockets.kickPlayer(playerToRemove);
};
// When a player disconnects without warning, e.g. closes window
this.playerDisconnects = function(playerToRemove) {
// Delete player from players array
this.players.splice(this.players.indexOf(playerToRemove),1);
// If less than min players
if (this.players.length < minPlayers) this.killGame();
// If less than max players
if (this.players.length < maxPlayers) {
this.needsPlayers = true;
}
};
this.selectJudges = function() {
this.judge = this.players.pop();
this.players = this.players.unshift(this.judge);
};
this.setWinner = function(winner) {
this.winner = winner;
};
Games[this._id] = this;
}
If you define your functions on the prototype than you do not need to "wait" for the functions to be defined because the instance will already have them when the constructor's code is called
function PublicGame (players) {
//...
this.judge = this.setJudge();
}
PublicGame.prototype.killGame = function(){
//...
};
PublicGame.prototype.playerExits = function(playerToRemove){
//...
};
PublicGame.prototype.setJudge = function(){
//do whatever
return whatever;
};
So unless your functions need to access some "private" variable (ie defined within the constructor, not a global variable), or other reason requiring it, define it on the prototype instead of defining it in the constructor and it will be ready to use.
You have to use javascript prototype !
Read the comments in the code sample.
/*
* utils functions
*
* dont take care about that
**/
var el = document.getElementById('dbg');
var jj = function(val,sep){return JSON.stringify(val , null , sep || '')}
var log = function(val){el.innerHTML+='<div><pre>'+val+'</pre></div>'};
var counterId = 0;
/************************************************************************/
// You have to use prototype
// here an example of what you can achieve
// we create a Player 'class'
var Player = function( name ){
this.id = counterId ++; //<-- an attribute
this.name = name; //<-- an attribute
this.setLevel(5);//<-- a method called at 'instanciation'
return this;
};
// a method available at instanciation time
Player.prototype.setLevel = function(level){
this.level = level;
return this;
};
// we create a new Player named Toto
var Toto = new Player('Toto');
log('Toto = ' + jj(Toto));//<-- utility function just to log
// we create a new Player named Jane
var Jane = new Player('Jane');
log('Jane = ' + jj(Jane)); //<-- utility function just to log
// we change the Level of Jane
Jane.setLevel(12);
log('Jane.setLevel(12)');//<-- utility function just to log
log('Jane = ' + jj(Jane));//<-- utility function just to log
<div id='dbg'></div>

Javascript class "Object has no method error"

I have a class called question . I am trying to call this display method from another class by creating its correspoding object. But I get this error. Will be glad if you can help me with this.
///////////////QUESTION///////////////
function Question(id, text){
this.id = id;
this.text = text;
}
function QType1(id, text, choices, answers){
//this is true or false
Question.call(this, id, text) ;
this.choices = choices;
this.answers = answers;
}
QType1.prototype = new Question();
//inherit Question
QType1.prototype.constructor = QType1;
QType1.Display = function(){
console.log("Display Question");
}
///////////////QUIZ//////////////////
function quiz(){}
quiz.prototype.SetHomeScreen = function(x,y){
var svgCanvas = CreateCanvas(x,y);
AddText(svgCanvas,100,50, quiz_input.Settings.Layout.Text);
console.log("Text Added");
start_but = AddStartButton(svgCanvas, 300, 250);
console.log("start button Added");
start_but
.on("click", function(d,i) {
startquiz();
});
var startquiz = function(){
console.log(this);
quiz.prototype.StartQuiz();
};
}
quiz.prototype.question_objs = [];
quiz.prototype.user_ans = [];
quiz.prototype.corr_ans = [];
quiz.prototype.LoadQuestions = function(){
for(var i=0, l=questions.length; i<l; i++){
this.question_objs.push(new QType1(questions[i].id, questions[i].settings.text, questions[i].settings.choices, questions[i].settings.answers));
}
console.log(this.question_objs);
}
quiz.prototype.DisplayQuestions = function(){
var i = 0;
var l = this.question_objs.length;
while(i < l){
console.log(this.question_objs[i] instanceof QType1);
this.question_objs[i].Display();
}
}
quiz.prototype.StartQuiz = function(){
quiz.prototype.LoadQuestions();
console.log("Starting Quiz");
quiz.prototype.DisplayQuestions();
}
The Error Message which I get is.
Thanks in Advance
Two possible causes:
you didn't declare function Qtype1() {} and
you didn't instatiate a qtype1 object like so var q = new Qtype1()
EDIT: you didn't make Display a method of QType1.
The only way you could have a QType1.Display method is if you had declared QType1 as a variable, like var QType1 = {}
That way you could have a Display method directly bound to the variable. But as you declared it as a constructor you need QType1.prototype.Display = function () { console.log('Display question...'); };
Also - your inheritance is a bit messy. You're calling Question.call(this, id, text) then you're declaring QType1.prototype = new Question() and then doing the same with the constructor. You need to review your javascript prototypal inheritance theory a bit.

Javascript prototype and issues accessing class

Family = function(name) {
this._Name = name;
}
Family.prototype = {
getName: function() {
return this._Name;
},
People: function(num) {
this._Number = num;
}
}
Family.People.prototype = {
clearNumber: function() {
this._Number = 0;
}
}
People is a nested class. Its parent class is Family.
I get the error that Family.People is undefined. Could someone correct the code above?
Working code
// function doesn't need "new" operator
var Family = function(name) { this._Name = name; };
Family.prototype = {
getName: function() { return this._Name; }, // missing comma
People: function(num) {
this._Number = num;
}
};
// work with prototypes
Family.prototype.People.prototype = {
clearNumber: function() { this._Number = 0; }
};
This will work. But you have to be aware, that when you call:
var f = new Family("Doe");
f.People is just an object constructor, and not an instance of some other object. You will have to instantiate it as well like:
f.members = new f.People(3);
Sou you have a constructor within your instance which is rather confusing.
A better approach
So it would probably be better if you'd write your prototypes this way:
var Family = function(name) {
this._Name = name;
this.getName = function() { return this._Name; };
};
Family.People = function(num) {
this._Number = num;
this.clearNumber = function() { this._Number = 0; };
};
This actually makes a class within a class (and not within instances). So upper lines would be called this way:
var f = new Family("Doe");
f.members = new Family.People(3);
Drill down of f instance would look like:
f
_Name
getName()
members
_Number
clearNumber()
Private variables
var Family = function(name) {
var _name = name;
this.getName = function() { return _name; };
};
Family.People = function(num) {
var _num = num;
this.getNumber = function() { return _num; }
this.clearNumber = function() { _num = 0; };
};
This way we make variables private and only accessible within so they can't be manipulated outside. You must always use functions to manipulate them. This makes it more robust especially when there are certain business rules related to variable values.
var f = new Family("Doe");
f._name; // this is undefined because "_name" is private closure variable
Drill down of f instance would now look more like a class object instance:
f
getName()
members
getNumber()
clearNumber()
Notice that you are assigning to Family.prototype.People then trying to access Family.People.
Family is not an instance of Family thus it does not have the properties of that class - Family is an instance of Function thus you are trying to access Function.prototype.People in that 3rd statement. (this is a bit of a simplification)
i.e. what you want to be doing is
Family.prototype.People.prototype = {
clearNumber:function(){this._Number = 0;}
}
You are also missing a comma before people, but I assume this is a typo...
You should declare the People constructor as a key in the Family object:
Family.People = function(num) {
this._Number = num;
}
The Family prototype will be in the prototype chain for new objects of type Family; not a part of Family itself.

Categories

Resources