Initializing object properties with objects own properties - javascript

I get the error:
Uncaught TypeError: Cannot read property 'interval' of undefined
When I try to initialize an object like this:
var loop = {
interval: 5 * 1000,
maxInterval: loop.interval * 12
};
So instead I have to do it like this:
var loop = {
interval: 5 * 1000
};
loop.maxInterval = loop.interval * 12;
Is there a better way of doing this?

No way.
But conceptually all you need is moving the constant one level up:
var defaultInterval = 5000;
var loop = {
interval: defaultInterval,
maxInterval: defaultInterval * 12
};

One option is using self executing function.
var loop = (function () {
var _ = {};
_.interval = 5 * 1000;
_.maxInterval = _.interval * 12;
return _;
})();

Related

Run code with a different outcome every 30 seconds

I have 2 variables called var1, and var2:
var var1 = 'foo';
var var2 = 'bar';
I'd like to be able to log one of these variables to the console every 30 seconds, with the variables alternating being logged (here's some pseudo-code):
Log var1 to console
Wait 30 seconds
Log var2 to console
Wait 30 seconds
Repeat
Any way to do this? I believe I should be doing something related with setInterval, but my solution:
setInterval(function() {
console.log(var1);
setTimeout(() => {
console.log(var2);
}, 30000);
}, 60000);
Doesn't seem to be the best solution. Is there a more efficient way to do this?
Just keep counter that enables you to alternate.
var counter = 0;
var var1 = "ONE!";
var var2 = "TWO!";
var frequency = 1000; //1000 is for illustration for the example
setInterval(function() {
if( counter++ % 2 == 0 ) {
console.log(var1);
} else {
console.log(var2);
}
}, frequency );
You want to use setInterval so that the interval is consistent and there is no execution time involved in establishing the time for the next async call.
You can pass in an object reference to control scope and also track the boolean and flip it:
setInterval(function(a){
a.bool = !a.bool
if(!a.bool){
console.log( a.var1)
return
}
console.log(a.var2)
}, 3000, {
bool : true,
var1 : 'value',
var2 : 'other value'
})
You could use setTimeout with two functions that call each other:
var var1 = 'foo';
var var2 = 'bar';
const log1 = () => {
console.log(var1);
setTimeout(log2, 30000)
}
const log2 = () => {
console.log(var2);
setTimeout(log1, 30000)
}
log1();
Here's a more generic approach: For a given list of values - it'll print the provided values in a cycle forever, and will wait for intervalMs between every print
/**
*
* #param {Array} values - collection of values to log
* #param {Number} intervalMs - the log interval
*/
function logValuesCyclicForever(values, intervalMs = 30000) {
let index = 0;
return setInterval(() => {
console.log(values[index]);
index = (index + 1) % values.length; // sets the location back to 0 when the last element is printed.
}, intervalMs);
}
var var1 = 'foo';
var var2 = 'bar';
logValuesCyclicForever([var1, var2]); // for your use case

How can javascript like varName.myFunction()

function CircleArea(Value) {
var Results = 3.14 * Value^2;
return Results;
}
So I want:
var Diameter = 30;
Diameter.CircleArea(); // Results 2826
Like:
var n = 30; n.toString() // Results 30
Syntax:
varName.myFunction();
You can but rarely should extend prototypes:
Number.prototype.circleArea = function() {
var value = this;
return Math.pow(value, 2) * Math.PI;
};
var num = 30;
console.log(num.circleArea()); // 2827.4333882308138
Your function accepts an argument .
So you will need to pass in Diameter like so :
CirclArea(Diameter)
Returns 2826

Calling a function if an operation is not true

I have not seen anything that specifically answers this question.
I intend to develop a text-based game that involves an action occurring every time an idle bar fills up(every x seconds passes)
I'm just trying to figure out the very basic layout of my javascript that will make the battling system in this game.
I'm trying to make the computer re-calculate pDamThisRound if pDamThisRound is not > baseD which is this case is 10.
If it is greater than baseD my code works and prints pDamThisRound. But if it isn't the code just prints nothing.
var baseD = 10;
var pStr = 25;
var pDam = Math.floor((baseD + pStr) / 2);
var pDamThisRound;
var pDamTR = function() {
pDamThisRound = (Math.floor(Math.random() * 2 * pDam));
};
pDamTR();
if(pDamThisRound > baseD) {
document.getElementById("h").innerHTML = pDamThisRound;
}
else {
pDamTR();
}
https://jsfiddle.net/qfnvf1y8/4/
the code just prints nothing
That's because there isn't any code which prints anything. Look at your else block:
else {
pDamTR();
}
What does that function do?:
var pDamTR = function() {
pDamThisRound = (Math.floor(Math.random() * 2 * pDam));
};
Nowhere do you produce any output.
Basically, if you want to print something then, well, print something. Just like you already do in your if block. For example:
document.getElementById("h").innerHTML = "something";
The function pDamTR is probably executing, the problem is that its assigning something to a variable, but doing nothing with it.
Here you go, a corrected version with a while operator:
https://jsfiddle.net/qfnvf1y8/6/
var baseD = 10;
var pStr = 25;
var pDam = Math.floor((baseD + pStr) / 2);
var pDamThisRound;
var pDamTR = function() {
pDamThisRound = (Math.floor(Math.random() * 2 * pDam));
};
pDamTR();
while(pDamThisRound <= baseD) {
pDamTR();
}
if(pDamThisRound > baseD) {
document.getElementById("h").innerHTML = pDamThisRound;
}
else {
pDamTR();
}
Regards,
Eugene
Several mistakes:
1) your else branch does not print anything
2) if you want pDamThisRound > baseD you need a while loop
while(pDamThisRound <= baseD) {
pDamTR();
}
printpDamTR();
function printpDamTR(){
document.getElementById("h").innerHTML = pDamThisRound;
}
The function printpDamTR would not be necessary, but it generally is a good idea to encapsulate such things, as you are probably going to use it more often. Also it increases the maintainability of your code since you loosen the dependencies between your JS and your HTML.
You can use setTimeout to help you, with something like this:
var baseD = 10;
var pStr = 25;
var pDam = Math.floor((baseD + pStr) / 2);
var timeoutDuration = 3000; // 3 seconds
window.setTimeout(function () {
// execute the check and the update logic here
var pDamThisRound = (Math.floor(Math.random() * 2 * pDam));
if(pDamThisRound > baseD) {
document.getElementById("h").innerHTML = pDamThisRound;
}
}, timeoutDuration);
This will execute the check every 3 seconds

Javascript error with returns and multiple the return

And I am sorry to bother with this noob-stuff, but currently new to all this. But learning slowly.
In the first lines of code im getting a return (in this code i get 20*2=40. in the next phase I want to multiplie the return (40) with 20. = 800. so in the outcome it will show 40 And 800. But i only get it to be in the outbox [function], it says. and a msg; "it looks like you didnt print out a value for newNumber".
What do I do wrong? Thanks for all help!
var timesTwo = function (number) {
return number * 2;
};
timesTwo(20);
var newNumber = function (tal) {
(timesTwo * tal);
console.log(newNumber);
};
newNumber(20);
What you need to do is assign the result to a variable, and in the second function return the result:
var timesTwo = function(number) {
return number * 2;
};
var twoTimesResult = timesTwo(20);
var newNumber = function (tal) {
return twoTimesResult * tal;
};
var result2 = newNumber(20);
console.log(result2);
If you wanted to be fancy you could also do the following:
function multiplier(num, multiplier) {
var by = num * multiplier;
return function (number) {
return number * by;
};
}
var multiplyResult = multiplier(20, 2);
console.log(multiplyResult(20));
I'm answering this question too because I think these types of things are fun.
Another approach you could take is the OOP approach.
From your example you have a common multiplier of 20 and a beginning constant of 2.
I would personally attack this problem like so to avoid multiple variables:
// Create a calc object
var Calc = (function () {
// Constructor
Calc = function () {
// Initial constant
this.current_val = 2;
}
// Prototype methods
Calc.prototype = {
// inc() method
inc: function () {
return this.current_val * 20;
}
}
// Return object
return Calc;
})();
// Object Instance
var obj = new Calc();
// Initial call to inc() -> 40
obj.current_val = obj.inc();
// Log
console.log(obj.current_val);
// Second call to inc() -> 800
obj.current_val = obj.inc();
// Log
console.log(obj.current_val);
// Third call to inc() -> 16000
obj.current_val = obj.inc();
// Log
console.log(obj.current_val);
I made a jsfiddle so you can see the output.

Javascript - Error creating objects on the fly

I am trying to simulate data to a function that would usually receive a JSON parsed data structure. When running this I get an error TypeError: can't convert undefined to object here: data.targets[i] = {
What am I doing wrong?
function SendFakeTargets(maxTargets, interval) {
var data = {};
data.timestamp = +new Date;
var time = data.timestamp * 0.0005;
var x = Math.sin(time) * 192 + 256;
var y = Math.cos(time * 0.9) * 192 + 256;
console.log(x, y);
for (var i = 0; i < maxTargets; i++) {
console.log(i);
data.targets[i] = { //error is here
id: i,
x: x + (i * 10),
y: y + (i * 10)
};
}
HandleTargetData(data);
setTimeout("SendFakeTargets("+maxTargets+", "+interval+")", interval);
}
you should previously declare
data.targets = [];
before using data.targets[i] inside the loop, otherwise data.targets is undefined. In a shorter way you could write
var data = {
timestamp : +new Date,
targets : []
};
And as a side note, never use strings in setTimeout/Interval. Do instead
setTimeout(function() {
SendFakeTargets(maxTargets, interval);
}, interval);
I think you need to initialize the targets array before using it, as it is undefined. You are defining data as
var data = {}
which is declaring it as an empty object, anything else that you're doing with it is added on the fly - arrays need to be initialized before you can call any index in them. I believe what you need to do is:
var data = { targets: [] }
You never declared "data.targets" as a an object so javascript doesn't know how to assign anything to it.
At the top of your code just define "targets":
data.timestamp = +new Date;
data.targets = {} or [];
...

Categories