How to create array of objects from a function call? - javascript

Let a function createSquare with accepts arguments side, color which returns an object with properties same as the arguments.The values assigned to the properties should be the values assigned to the function.Other than these properties the object also has one method which return the area of square.Now create an array Box this array should contain the 3 objects which are created by calling createSquare function.And the objects should have the values[(3,black) ,(4,red) ,(5,green) ].
I have used ES5 javascript for this. The initial part I have used constructor to create the object like
function CreateBox(side, color) {
this.side = side;
this.color = color;
//function-1
areaOfSquare = function () {
let a = this.side * this.side;
console.log(a);
};
}
The Second part I am confused how to push the values of object into array.(this is how I thought of)
let box = [];
for (let i = 0; i < 3; i++) {
box[i].push(CreateBox(3, "black"));
}

In order to return an Object the function or class should be initialize the object by adding new keyword like new CreateBox() before the function/class call, example:
let box = [];
for (let i = 0; i < 3; i++) {
box[i].push(new CreateBox(3, "black")); // only thing missing the new keyword
}
//or
let array = [new CreateBox(3, "black"), new CreateBox(4, "yellow"), new CreateBox(5, "blue")]

// Define constructor like method
const CreateBox = (function () {
function CreateBox(side, color) {
this.side = side;
this.color = color;
}
CreateBox.prototype.area = function () {
return Math.pow(this.side, 2);
}
return CreateBox;
}());
// Add boxes into Array with new CreateBox(side, color);
let box = [];
for (let i = 0; i < 3; i++) {
box.push(new CreateBox(i + 1, "black"));
}
// Check the data
box.forEach(b => console.log(`side = ${b.side}, color = ${b.color}, area = ${b.area()}`));

Related

Javascript foreach not executing for all objects

I currently have an object that adds itself to an array whenever a new one is created. Eventually, I want to remove all of the references in the array so I can add new ones.
I've created an object method (this.removeFromArray()) that looks for itself in the array and splices itself out. removeAll() runs a for loop that makes each object in the array run removeFromArray(), so I expect that when I try to read out the items in the array, I should get nothing.
Instead, depending on the amount of objects created, I get one or two left behind. How can I fix this and have all objects in the array cleared out?
var objArray = [];
function obj(name) {
objArray.push(this);
console.log("Created "+name);
this.name = name;
this.removeFromArray = function() {
objArray.splice(
objArray.findIndex(function(e) {
return e == this;
}),
1
);
}
}
function removeAll() {
for (var i = 0; i <= objArray.length - 1; i++) {
objArray[i].removeFromArray();
}
}
var foo = new obj("foo");
var bar = new obj("bar");
var cat = new obj("cat");
var dog = new obj("dog");
var bird = new obj("bird");
removeAll();
for (var i = 0; i <= objArray.length-1; i++) { //Check the values in the array for leftovers
console.log(objArray[i].name);
}
//Expected nothing in the console but the creation messages, got foo and bar instead
If you want to simply delete all the created object, edit removeAll() function like below:
Note that you have to create a variable for objArray.length, not directly put the objArray.length to for() loop.
function removeAll() {
var len = objArray.length;
for (var i = 0; i <= len - 1; i++) {
objArray.splice(0,1);
}
}
better way to achieve this would be to utilize inheritance through prototype. it is better than creating a function inside the constructor object.
var objArray = [];
function Obj(name) {
this.name = name;
objArray.push(this);
}
Obj.prototype.removeFromArray = function() {
var i = -1,
len = objArray.length,
removed = null;
while (++i < len) {
if (objArray[i] === this) {
removed = objArray.splice(i, 1);
removed = null; //nullify to free memory, though not that necessary
break;
}
}
};
Obj.prototype.removeAll = function() {
var len = objArray.length,
removed = null;
//note that i started from the last item to remove to avoid index out of range error
while (--len >= 0) {
removed = objArray.splice(len, 1);
removed = null; //nullify to free memory, though not that necessary
}
};

Javascript Accessor properties confusion

I am not sure why this code gives me an error. All I want to do is create an object that has an array as a property. I want to achieve this with a setter and getter but for some reason when I do this.array = [] inside the setArray function I get Maximum call stack size exceeded. What am I doing wrong ? What am I missing about Javascript's accessor properties.
var obj = {
set array(size) {
this.array = [];
for (var i = 0; i < size; i++){
this.array[i] = i;
}
}
};
var myObj = Object.create(obj);
myObj.array = 20;
You're assigning to a property with a setter from within the setter, which is why it recurses forever:
var obj = {
set array(size) { // <== The property is called `array`
this.array = []; // <== This calls the setter
for (var i = 0; i < size; i++){
this.array[i] = i; // <== This would fail because there's no getter
}
}
};
You have to store the value elsewhere, for instance here we create a private scope and close over a variable:
var obj = (function() {
var array = [];
return {
set array(size) {
array = []; // No `this` here
for (var i = 0; i < size; i++) {
array[i] = i; // No `this` here
}
},
showArray() {
console.log(array);
}
};
})();
var myObj = Object.create(obj);
myObj.array = 20;
myObj.showArray();
You asked about avoiding the function. You need the function to make the value of the property truly private. But if you don't want to use it for some reason, and you're not that bothered about it being truly private, you can do what Zoltán Tamási did in his answer: Use another property on the same object. His answer uses a _ prefix on the underlying property (e.g., _array), which is a very common convention in JavaScript for "leave this alone, it's 'private'" even though there are no private properties. The fact is that even in languages with truly private properties (like Java, where they're called instance fields), there's usually some form of powerful reflection mechanism you can use to get around it, so...
If you do that, one thing to consider is whether you want that private property included in JSON if you serialize. If not, just implement toJSON as well so you can control which properties are included during serialization:
var obj = {
_array: [],
foo: "a value to include in JSON",
set array(size) {
this._array = []; // Note the _
for (var i = 0; i < size; i++) {
this._array[i] = i;
}
},
showArray() {
console.log(this._array);
},
toJSON() {
return {
// Here we list only the properties we want to have
// included in the JSON
foo: this.foo
};
}
};
var myObj = Object.create(obj);
myObj.array = 20;
myObj.showArray();
console.log(JSON.stringify(myObj));
You are using the setter inside the setter itself when you write this.array = []. Introduce another member called for example _array and fill that in the setter of the array property.
var obj = {
_array: [],
set array(size) {
for (var i = 0; i < size; i++){
this._array[i] = i;
}
}
};
var myObj = Object.create(obj);
myObj.array = 20;
You had mentioned that you wanted to use setters and getters, this snippet just uses obj.array instead of showArray to view the object's array.
var obj = (function() {
var _array = [];
return {
get array(){
return _array;
},
set array(size) {
_array = [];
for (var i = 0; i < size; i++) {
_array[i] = i;
}
}
};
})();
obj = Object.create(obj);
obj.array = 20;
console.log(obj.array);

Js lodash return the same sample every time

I want to generate samples with lodash and it return me the same numbers for each line. what im doing wrong?
var primaryNumsCells = _.range(50);
var extraNumsCells = _.range(20);
var lottery = {lineConfigurations: []};
var numsConfig = {lineNumbers: {}};
for( var i = 0; i < 2; i ++ ) {
numsConfig.lineNumbers.primaryNumbers = _.sample(primaryNumsCells, 5);
numsConfig.lineNumbers.secondaryNumbers = _.sample(extraNumsCells, 2);
lottery.lineConfigurations.push(numsConfig);
}
console.log(lottery);
The results of the first object and second object of the primary and secondary numbers is the same;
here is the fiddle:
http://jsbin.com/vavuhunupi/1/edit
Create a new object inside a loop. It's easy to do with a plain object literal (dropping the variable):
var lottery = {lineConfigurations: []};
for (var i = 0; i < 2; i++) {
lottery.lineConfigurations.push({
lineNumbers: {
primaryNumbers: _.sample(primaryNumsCells, 5),
secondaryNumbers: _.sample(extraNumsCells, 2)
}
});
}
As it stands, at each step of the loop you modify and push the same object (stored in numsConfig var).
And here goes a lodash way of doing the same thing:
var lottery = {
lineConfigurations: _.map(_.range(2), function() {
return {
lineNumbers: {
primaryNumbers: _.sample(primaryNumsCells, 5),
secondaryNumbers: _.sample(extraNumsCells, 2)
}
};
})
};

Javascript Inheritance: One Subclass gets the Prototype, the other doesn't

I have a SuperClass "class", and this class is to be inherited (via the prototype chain) by SubClassA and SubClassB. However, while the inheritance appears to work for SubClassA, it fails for SubClassB. The code is below:
function SuperClass(childCell){
this.childCell = childCell;
this.children = new Array(9);
for(i=0; i<9; i++) {
this.children[i] = new this.childCell();
}
}
function SubClassA(){
this.num = 1;
}
SubClassA.prototype = new SuperClass(SubClassB);
function SubClassB(){
this.num = 2;
}
SubClassB.prototype = new SuperClass(SubClassC);
function SubClassC(){
this.num = 3;
}
var x = new SubClassA();
In this code, I set x to an object of SubClassA, and this should in turn give me a children property containing 9 SubClassB objects. It does this properly, but in turn, each SubClassB object should contain 9 SubClassC objects. However, after inspecting the console, I found that none of the SubClassB objects actually contain the childCell or the children properties that it was supposed to inherit via prototype.
In other words, x.children[0] returned SubClassB {num: 2}, and had none of the other properties.
Why does the inheritance work for SubClassA but not SubClassB?
try reorder your declaration sample like
function Parent(childCell){
this.childCell = childCell;
this.children = new Array(9);
for(var i=0; i<9; i++) {
this.children[i] = new this.childCell();
}
}
function ChildA(){
this.num = 1;
}
function ChildB(){
this.num = 2;
}
function ChildC(){
this.num = 3;
}
ChildB.prototype = new Parent(ChildC);
ChildA.prototype = new Parent(ChildB);
your problem - you call ChildB constructor before you add prototype to it
UPDATE
#Bagavatu when you create object you use prototype which set for constructor function, then you can change prototype properties and this changes will be apply to all objects with this prototype.
In your case you change reference to prototype so it does not apply to object which was created before. You can test it in simple example
function A() {this.cell = 10}
function B() {this.num =1}
var b1 = new B(); // b1 = {num:1}
B.prototype = new A();
var b2 = new B(); // b1 = {num:1}, b2 = {num:1, cell:10}
I usually dont dig that much deep.But when we use sub classing in javascript,folllow the following pattern.
function Superclass() { }
Superclass.prototype.someFunc = function() { };
function Subclass() { }
Subclass.prototype = new Superclass();
Subclass.prototype.anotherFunc = function() { };
var obj = new Subclass();

Javascript: sort objects

function Player() {
var score;
this.getScore = function() { return score; }
this.setScore = function(sc) { score = sc; }
}
function compare(playerA, playerB) {
return playerA.getScore() - playerB.getScore();
}
var players = [];
players['player1'] = new Player();
players['player2'] = new Player();
Array(players).sort(compare);
I have code that is similar to the above. When I step through the code with a debugger, the compare function never gets called and the array isn't sorted. I'm not sure what's wrong with my code?
It's not sorting because you have specified the keys that the variables within the array belong on. Sorting will only move the objects on integer-valued keys. You should see your sorting work if you create your array as follow:
var players = [new Player(), new Player()];
though, of course, it won't be very effective since you have neither a score on which to sort or a method of identifying them. This'll do it:
function Player(name, score) {
this.getName = function() { return name; }
this.getScore = function() { return score; }
this.setScore = function(sc) { score = sc; }
}
function comparePlayers(playerA, playerB) {
return playerA.getScore() - playerB.getScore();
}
var playerA = new Player('Paul', 10);
var playerB = new Player('Lucas', 5);
var playerC = new Player('William', 7);
var players = [playerA, playerB, playerC];
for (var i = 0; i < players.length; i++)
alert(players[i].getName() + ' - ' + players[i].getScore());
players.sort(comparePlayers);
for (var i = 0; i < players.length; i++)
alert(players[i].getName() + ' - ' + players[i].getScore());
Hope that helps.
The main problem lies in this line:
Array(players).sort(compare);
Array(something) makes an array with something as its element.
console.log(Array(players)); //[[player1, player2]]
Use numeric indexed array instead of using object like array as in players['player1']
Run the following code (replace console.log with alert if you don't have Firebug).
function Player() {
var score;
//return this.score - else it returns undefined
this.getScore = function() { return this.score; }
this.setScore = function(sc) { this.score = sc; }
}
function compare(playerA, playerB) {
console.log("called " + playerA.getScore() + " " + playerB.score);
//compare method should return 0 if equal, 1 if a > b and -1 if a < b
return (playerA.getScore() == playerB.getScore()) ? 0
: ((playerA.getScore() > playerB.getScore()) ? 1 : -1);
}
var players = [];
players[0] = new Player();
players[1] = new Player();
players[2] = new Player();
players[3] = new Player();
players[0].setScore(9);
players[1].score = 14;
players[2].score = 11;
players[3].score = 10;
players.sort(compare);
console.log(players);//prints sorted array
It's probably because you don't have any "array values" inside your array - textual indexes are not regarded as array values but as object propertiest (arrays are "objects in disguise" in javascript). You can add as many properties to any object but array specific methods like sort take only "real" array members as their parameteres (i.e. only with numerical indexes)
var arr = new Array()
arr[0] = 1
arr[1] = 2
arr["textual_index"] = 3
alert(arr.length);
The last line alerts "2" not "3" since there are only two values with numeric indexes.
you can also use like below:
var a = [];
a.push(obj1);
a.push(obj2);
a.sort(compare);
so you can use push method rather than an integer index

Categories

Resources