For Loop inside Function, Array Enumeration - javascript

Having some difficulty with this code for my assignment.
I'm supposed to create two functions.
the first function is called calledInLoop that will accept one parameter and log the parameter.
calledInLoop = function (parameter) {
console.log(parameter);
}
the second function is called loopThrough that will accept an array, loop through each, and invoke the calledInLoop function. The result should be each element of the array is console logged.
loopThrough = function (array) {
for (var i = 0; i < array.length; i++){
calledInLoop(array[i]);
};
}
myArray = ['dog', 'bird', 'cat', 'gopher'];
console.log(loopThrough(myArray)); returns each element on its own console.log line but then returns undefined. Why is this?

The call to console.log in console.log(loopThrough(myArray)); is only printing out undefined. It does this because loopThrough does not return anything, so it defaults to undefined.
The elements in the array are printed by a call to calledInLoop in loopThrough, which in turn calls console.log.

Your loopThrough function does not return any value when called. Hence it's return value is undefined.
loopThrough = function (array) {
for (var i = 0; i < array.length; i++)
calledInLoop(array[i])
return 1
}
Now this will return you 1.
Similarly you can return any other values.

Related

Why object.values(arguments) instead of directly slicing “arr”?

This is the question Prompt:
You will be provided with an initial array (the first argument in the destroyer function), followed by one or more arguments. Remove all elements from the initial array that are of the same value as these arguments.
This is the model solution:
function destroyer(arr) {
let valsToRemove = Object.values(arguments).slice(1);
for (let i = 0; i < arr.length; i++) {
for (let j = 0; j < valsToRemove.length; j++) {
if (arr[i] === valsToRemove[j]) {
delete arr[i];
}
}
}
return arr.filter(item => item !== null);
}
My question is: why must we assign to “valToRemove” “Object.values(arguments).slice(1)” and not “arr.slice(1)”
Look at the definition again:
an initial array (the first argument in the destroyer function), followed by one or more arguments
So arr is "an initial array (the first argument in the destroyer function)"
Object.values(arguments).slice(1); is "followed by one or more arguments"
If you sliced arr then you might as well just say:
function destroyer(arr) {
return arr[0];
}
… which is very different.
That said, the modern approach to this would be to use rest parameter syntax:
function destroyer(arr, ...valsToRemove) {

How to get the function arguments value?

I want to simplify my email validation by looping through all the function arguments value using arguments[i] but it returns "undefined".
function checkInputRequired(companyNameValue, contactNameValue, publisherEmailValue, publisherEmailConfirmValue)
{
// The arguments object is an Array-like object corresponding to the arguments passed to a function.
for (var i = 0; i < arguments.length; i++)
{
// print out 4 undefined
console.log(arguments[i]);
}
}
check this out
function checkInputRequired(companyNameValue, contactNameValue, publisherEmailValue, publisherEmailConfirmValue)
{
// The arguments object is an Array-like object corresponding to the arguments passed to a function.
for (var i = 0; i < arguments.length; i++)
{
// print out 4 undefined
console.log(arguments[i]);
}
}
checkInputRequired('ddd','bbbbb','sssss','dddddddddd');
when you call the function it will display the values otherwise it show the default value undefined.

How does a function gets passed in to another function?

I have a forEach function defined to do "something" with all the items in an array:
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]);
}
var numbers = [1, 2, 3, 4, 5], sum = 0;
So I could do:
forEach(numbers, console.log);
And it would print out all the numbers because 'console.log(array[i])' prints the number to the console.
I get that part.
Here's where I'm stuck: If I pass the function below into the place of the action parameter, instead of 'console.log' then at what point does the function know about every element?
forEach(numbers, function(number) {
sum += number;
});
console.log(sum);
// 15
How does it get evaluated? If I pass console.log into the last problem and it still has to be evaluated as 'console.log(array[i])' with the '(array[i])' code next to whatever parameter is being passed in, then doesn't that get applied to the entire function too since that function is the parameter? Such as below:
function(number) { sum += number; }(array[i])
at what point does the function know about every element
At no point (just like when you pass in console.log).
The forEach function calls it on this line:
action(array[i]);
At which point, it only knows about a single value from the array because that is all that is passed into it.
(It also knows about the sum variable because that is defined in a wider scope than the function).
How does it get evaluated?
It creates a new scope (with array, action and i variables) and assigns the function to the action variable - that's a function invocation.
Your
var sum = 0;
forEach([1, 2, 3, 4, 5], function(number) {
sum += number;
});
is just the same as
var sum = 0;
{ // let's assume block scope here
var array = [1, 2, 3, 4, 5],
action = function(number) {
sum += number;
},
i;
for (i = 0; i < array.length; i++)
action(array[i]);
}
If I pass console.log into the last problem and it still has to be evaluated, then doesn't that apply to the entire function too since that function is the parameter?
Yes, exactly. You are passing a function object - and whether get that by referencing the console.log variable or by creating it on the fly (with the function expression) doesn't matter to forEach. It only will get executed with action(…) - where the array[i] value is passed for the number parameter of your function.
In JavaScript, functions are first-class citizens. That means they can be treated as variables, just like strings, numbers, etc.
When you do:
forEach(numbers, function(number) {
sum += number;
});
You are passing forEach an anonymous function. Instead of the function being in a variable, it's created on-the-fly. Inside your forEach function, action will contain your anonymous function.
In for for loop, the action function is called for each element.
Heres the solution to your problems:
function forEach(array, action) {
for (var i = 0; i < array.length; i++){
if(typeof action == 'function'){
action(array[i]);
}else{
var slices = action.match(/(.+)\.([a-zA-Z0-9]+)/);
var object = eval(slices[1]);
var action = slices[2];
object[action](array[i]);
}
}
}
I've tested it with both scenarios and it works like magic

var scope in javascript functions

I have the following small code snippet with the following expected and real output. My question is quiet simple. Why is it printing it this sequence? and how to I print the expected output?
Gr,
expected result:
0
1
2
0
1
2
real result:
0
1
2
3
3
3
this is the code:
var functions = [];
for (var i=0; i<10; i++) {
console.log (i);
functions.push (function () {
console.log (i);
});
};
for (var j=0; j<functions.length; j++) {
functions[j] ();
};
The functions that you push into the array doesn't log the value of i as it was when the function was created, they log the value of i at the time that the function is called.
Once the first loop ends, the value of i is 10, therefore any of the functions called after that will log the value 10.
If you want to preserve the value of i at different states, you can use a closure to make a copy of the value:
for (var i=0; i<10; i++) {
console.log (i);
(function(){
var copy = i;
functions.push (function () {
console.log (copy);
});
})();
};
The local variable copy will get the value of i and retain the value. You can also pass the value as a parameter to the function:
for (var i=0; i<10; i++) {
console.log (i);
(function(copy){
functions.push (function () {
console.log (copy);
});
})(i);
};
The expected result should be:
1
2
...
10
10
10
... 7 more times
The reason for this is simple. The console.log(i) inside your loop is correctly printing the value of i at each iteration of the loop. When you create and push a function into the functions array, what you're doing is closing each of those functions over the same variable i. At the end of your loop, i no longer satisfies your loop condition, so i = 10 is true. As a result, since each of those functions is going to execute console.log(i), and they're each closed over the same i, which now has value 10, you should expect to see the value 10 printed 10 times.
To prevent this, you will want to make a function which returns a function rather than creating functions directly in a loop:
var functions = [], i, j;
function createEmitter(i) {
return function () {
console.log(i);
};
}
for (i = 0; i < 10; i++) {
console.log(i);
functions.push(createEmitter(i));
};
for (j = 0; j < functions.length; j++) {
functions[j]();
};
Now, each of those created functions is closed over its own private scope variable, which resolves the problem.
You should update your code example to be i < 3 so that your results and function match up.
The functions you push into the functions array are storing a reference to the variable i, which after executing the top loop, is 10. So when it executes, it will go get the variable i (which is 10) and print that 10 times.
Here's a good way to see this in action:
for (var i=0; i<10; i++) {
console.log (i);
};
console.log(i) //=> 10
When you are using a variable, remember that the variable can change, it's not frozen at it's current value. You are only holding on to a reference to something else.
To fix this problem, I would run this type of minor refactor on the code (because the other answers have already created an extra scope, figured I'd give you something different). Rather than storing 10 functions, just store the numbers and execute them with a single function. This is a more elegant way to write it anyway, and takes up less space. I'm sure this example was abstracted from whatever code was really giving you the problem, but the general pattern still applies.
numbers = [];
for (var i=0; i<10; i++) {
console.log (i);
numbers.push(i);
};
numbers.forEach(function(i){
console.log(i);
});

JavaScript "arguments" -passing a function with other parameters

Function multiply below is passed a callback function "addOne". Function multiply returns [3,5,7].
Since the callback function addOne is one of the arguments of function multiply, and since the arguments of function multiply are all multiplied by 2, why doesnt the callback function itself (i.e. addOne) get multiplied by 2? In other words, instead of function multiply returning [3,5,7], I would have expected it to return [3,5,7, NAN] since the function is not a number?
Does JavaScript interpreter just somehow know not to multiply it by 2?
function addOne(a) {
return a + 1;
}
function multiply(a,b,c, callback) {
var i, ar = [];
for (i = 0; i < 3; i++) {
ar[i] = callback(arguments[i] * 2);
}
return ar;
}
myarr = multiply(1,2,3, addOne);
myarr;
Because your loop's condition is <3 (hehe) which means it won't subscript the callback (the last element).
You should consider making the callback the first argument always, and splitting the arguments like so...
var argumentsArray = Array.prototype.slice.call(arguments),
callback = argumentsArray.shift();
jsFiddle.
Then, callback has your callback which you can call with call(), apply() or plain (), and argumentsArray has the remainder of your arguments as a proper array.
This line for (i = 0; i < 3; i++) { is protecting you.
You stop before it hits the callback argument
Because you are running the the loop for the first 3 args only. i < 3 runs for i=0, i=1,i=2

Categories

Resources