How can I change the function passed params? - javascript

How can I change the function passed params?
function minus_num(num) {
num -= 1
}
var num_test = 10
while (num > 0){
minus_num(num_test)
}
console.log(num) // there I want to get the 0, but it is infinite loop, because the `num` will have a copy in the function.
How can I change the num_test itself?

You need the function to return the value after being subtracted, and then you need to assign the result of that to num_test.
But num is never explicitly declared in your code. You probably wanted to put num_test in the loop instead:
function minus_num(num) {
return num - 1
}
var num_test = 10
while (num_test > 0){
num_test = minus_num(num_test)
}
console.log(num_test)

Primitives are passed by value, so you cannot change them in place. Instead you must return the changed value from the function and assign it back to the same variable:
function minus_num(num) {
num -= 1;
return num;
}
var num_test = 10
while (num_test > 0) {
num_test = minus_num(num_test)
}
console.log(num_test);
For your current implementation, you will get an error that num is not defined because you never declared it before the usage.
Please read this post to find out more on variable passing to functions.

I think it should be
function minus_num(num) {
return num - 1
}
var num_test = 10
while (num_test > 0){
num_test = minus_num(num_test)
}
console.log(num_test)

Related

Invoke a function with is faster than directly invoking?

I tested performance with a script from "Secrets of Javascript Ninja":
function isPrime(number) {
if (number < 2) {
return false;
}
for (let i = 2; i < number; i++) {
if (number % i === 0) {
return false;
}
}
return true;
}
console.time("isPrime");
isPrime(1299827);
console.timeEnd("isPrime");
console.time("isPrime");
isPrime.apply(1299827);
console.timeEnd("isPrime");
And the result is:
isPrime: 8.276ms
isPrime: 0.779ms
Seems that "apply" is faster?
Your comparison is not accurate, because the first parameter passed to apply is the this value of the called function, and the second parameter passed to apply is an array of parameters that function is to be called with. So, your apply is not calling isPrime with any parameters, so no iterations run, because the condition i < number is not fulfilled when i is 2 and number is undefined:
function isPrime(number) {
console.log('calling with ' + number);
if (number < 2) {
return false;
}
for (let i = 2; i < number; i++) {
if (number % i === 0) {
return false;
}
}
return true;
}
console.time("isPrime");
isPrime(1299827);
console.timeEnd("isPrime");
console.time("isPrime");
isPrime.apply(1299827);
console.timeEnd("isPrime");
If you use apply properly and pass in undefined, [1299827], the result is as expected, very similar. You should also use performance.now() for better precision than console at the millisecond level, though for such a quick operation you might not see that might difference anyway:
function isPrime(number){
console.log('calling with ' + number);
if(number < 2) { return false; }
for(let i = 2; i < number; i++) {
if(number % i === 0) { return false; }
}
return true;
}
const t1 = performance.now();
isPrime(1299827);
const t2 = performance.now();
isPrime.apply(undefined, [1299827]);
console.timeEnd("isPrime");
const t3 = performance.now();
console.log(t2 - t1);
console.log(t3 - t2);
The syntax for .apply is
function.apply(thisArg, [argsArray])
the first parameter thisArg refers to the value of 'this' when calling the function, in your case isPrime.apply(1299827) you passed in 1299827 as 'this' but no parameter, so it's really isPrime(), the for loop is not excuted so it's faster
more on .apply here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
You have to read this.
reference: https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
This point is Array.prototype.apply(context = this, args = []), so your code is wrong.
Change your code to this.
// incorrect.
isPrime.apply(1299827);
// correct.
isPrime.apply(this, 1299827);

How to make the return variable hold a new value after Increment/Decrementing it in a function?

Everytime I run this function, the p1_Balance will always reset back to 10 and will not hold the new value of an increment or decrement.
function Balance() {
var p1_Balance=10;
var x= Math.floor(10*Math.random());
if (x<5) {
p1_Balance=p1_Balance-1;
} else {
p1_Balance=p1_Balance+1;
}
return p1_Balance;
}
Pass p1_Balance into the function instead of initializing it each time the function is called with: var p1_Balance = 10;
p1_Balance should be declared outside the scope of the function (meaning not within the function itself). Otherwise, each time the function is called, the initializer that sets the value to 10 runs as well.
var p1_Balance=10;
function Balance(){ ...
You can use Javascript closures to create a function that does what you want, as you can see below:
var Balance = (function() {
var p1_Balance = 10;
return function() {
var x = Math.floor(10 * Math.random());
if (x < 5)
return p1_Balance += 1;
else
return p1_Balance -= 1;
};
})();
for (var i = 0; i < 10; i++)
console.log(Balance());
Alternatively, you will need to define the p1_Balance variable outside the function or pass it as an argument.
There could be several solutions:
one is declaring p1_Balance as a global variable.
var p1_Balance=10;
function Balance(){
var x= Math.floor(10*Math.random());
if (x<5) {
p1_Balance=p1_Balance-1;
}
else {
p1_Balance=p1_Balance+1;
}
return p1_Balance;
}
another is you could pass balance as a function parameter:
function Balance(p1_Balance){
var x= Math.floor(10*Math.random());
if (x<5) {
p1_Balance=p1_Balance-1;
}
else {
p1_Balance=p1_Balance+1;
}
return p1_Balance;
}
.....
value = Balance(10);// value=something that you want to change by that function.

Store and compare with previous result where do I place counter

Hello I need to compare a previous result that I'm getting from an API with the new one. The thing is that I don't know the value that I'll be getting. Therefore, I use a random function and a variable called oldShowNumber that will store the old result from the API and compare it to the new one which I'll call newrandom.
I tried to use a counter so the next time it enters inside the counter > 1 condition. Am I overcomplicating myself?
This is my script:
var array= ["100", "200", "300", "300"]
var newrandom = array[Math.floor(Math.random() * array.length)];
let counter= 1
var oldShowNumber= "";
(function (param){
if(counter <= 1){
oldShowNumber += param
counter +=1
} else if( counter > 1){
if(oldShowNumber === param){
console.log("They are the same it should stop")
}
}
})(newrandom)
console.log(oldShowNumber)
You need to store the information whether you already have an old number and if yes, the value of said number.
A common technique is to initialize a variable with to undefined to refer to the first case and assign a number in the second case.
Therefore: Initialize oldShowNumber with undefined and replace
var oldShowNumber= "";
....
if (counter <= 1) {
...
} else if (counter > 1) {
...
}
with
var oldShowNumber; // identical with: var oldShowNumber = undefined;
....
if (oldShowNumber === undefined) {
...
} else {
...
}

variable is coming back as undefined jQuery

I am trying to call a function in jQuery and the variable is coming back as undefined in the console
var divide = function(entry) {
var entry = number
for (var i = 1; i <= entry; i++) {
if (i % 5 === 0 && i % 3 === 0) {
return "pingpong";
} else if ( i % 3 === 0) {
return "ping";
} else if (i % 5 === 0 ) {
return "pong";
} else {
return i;
}
}
}
$(document).ready(function(){
$("form#number").submit(function(event){
var number = parseInt($("#userNumber").val());
var pingpong = divide (number);
$("#result").text(pingpong);
event.preventDefault();
});
});
Why do you need a for-loop for this ? Assigning number to entry will not help as number is within the local scope of $(document).ready which will be undefined for divide. As you are passing entry as an argument, use that for conditions
Try this:
var divide = function(i) {
if (i % 5 === 0 && i % 3 === 0) {
return "pingpong";
} else if (i % 3 === 0) {
return "ping";
} else if (i % 5 === 0) {
return "pong";
} else {
return i;
}
}
$(document).ready(function() {
$("form#number").submit(function(event) {
var number = parseInt($("#userNumber").val());
var pingpong = divide(number);
$("#result").text(pingpong);
event.preventDefault();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<form id='number'>
<input type="number" id='userNumber'>
<input type="submit">
<div id="result"></div>
</form>
Fiddle here
I think you may be confused about how arguments are passed into functions.
You have:
function divide ( entry ) { // defining divide
var entry = number; // this line is counter-productive
...
}
....
var number;
... divide(number); // calling divide
When you call the divide() function, the value of the variable number is automatically copied into the variable entry in divide(). Then you attempt to do the same thing with var entry = number; but number is not available in divide() so this fails. Lets suppose that number was globally available do this line did not cause an error. It might do what you want in this case, but a function whose argument is immediately ignored and overwritten is not very useful. Imagine you wanted to call it with two different values:
divide(number);
...
divide(someothernumber);
that wouldn't work because of the var entry = number; line -- you could never successfully pass someothernumber into divide(). Delete the line:
var entry = number;
from divide() and you will be much happier.
you try to delete "var entry = number"

proper use of the array.push method

if I have a simple test function that adds even numbers to an array:
function isEven(n){
var enumbers = [];
if (n % 2 == 0){
enumbers.push (n);
}
}
how can I increment my parameter until I have a set number of members in my array? for instance, I've tried this:
function isEven(n){
var enumbers = [];
while ( enumbers.length < 10){
if (n % 2 == 0){
enumbers.push (n);
}
console.log (enumbers);
n = n + 1;
isEven(n);
}
}
isEven(1);
but it seems to just create a new array for each number until it finally throws a range error (maximum call stack size exceeded).
It's creating that array multiple times because you're constantly calling that function with:
isEven(n);
You're also not comparing to the length of the array, just the array. Add .length to enumbers. Try changing to:
var enumbers = [];
while ( enumbers.length < 10){
if (n % 2 == 0){
enumbers.push (n);
}
console.log (enumbers);
}
I'm not sure if I understood your question.
But you shouldn't use global variables, and it is unnecessary to call your function recursively inside a while loop.
The error maximum call stack size exceeded is your browser trying to break a infinity loop.
This is what you need.
Examples here jsFiddle1 and jsFiddle2
function isEven(n) {
var enumbers = [];
while (enumbers.length < 10) {
if (n % 2 == 0) {
enumbers.push(n);
}
n++;
}
return enumbers;
}
Setup a test
var n = 1;
var evenArray = isEven(n); //call isEven function and it returns an array
document.body.innerHTML = evenArray; //2,4,6,8,10,12,14,16,18,20
The problem is that (enumber < 10) apparently always evaluates to true, causing an endless loop. But it is this comparison that is wrong, since you're comparing an integer with an array I think you're trying to get the array length?:
while (enumbers.length < 10) {
Another thing. enumbers is a local variable, so each call to isEven has it's own array. Therefore, the functions is called recursively, over and over again.
I suggest you create the array outside of is even method
I would have written something like:
function isEven(n,enumbers){
while(enumbers < 10){
if (n % 2 == 0){
enumbers.push (n);
}
console.log (enumbers);
n = n + 1;
isEven(n, enumbers);
}
}
var enumbers = [];
isEven(1,enumbers);

Categories