I encountered an error while coding in javascript. I want to pass an array as a function parameter from main function to another function, do operations in function and the return edited array.
However, as far as I understood, when I di\o this
var1 = function_1(var2) where var2 is an array, it doesn't actually pass the array to a function.
I want to do this with standard JavaScript library.
Thank you in advance.
To demonstrate how it would work:
var var2 = [1,2,3]
var var1 = function_1(var2)
function function_1(a) {
alert(a)
return a
}
Related
In reviewing the following article: https://html-online.com/articles/get-url-parameters-javascript/
They show the following example:
var number = getUrlVars()["x"];
Can someone please explain the syntax where the parameter is outside of the function?
If it was written as the following would you have asked the question?
var myVariables = getUrlVars()
var number = myVariables["x"];
The function call getUrlVars is returning an object {x: 123} and the developer is reading a property of the object right away. Instead of writing it in two steps, they wrote it as one.
Doing it that way is great if you are only reading one property from the object, but if you want to read more than one, it would be better to write it out by storing getUrlVars() into a variable and than using that to read the properties. That way you are not executing getUrlVars more than once.
var num = getUrlVars()["x"]; This expression is used when the called function is returning a object and you want to get only desired value out of the returned object. Here ["x"] is not a parameter it used as object property accessor.
function getUrlVars(){
return{
'x': 'This is x',
'y': 'This is y'
}
}
var num = getUrlVars()["x"];
console.log(num)
var number = getUrlVars('["x"]'); In this expression you're passing [x] as parameter to a function.
This question already has answers here:
Pass a JavaScript function as parameter
(15 answers)
Closed 5 years ago.
This is an example from "Eloquent JavaScript" book (I think you know the book):
function groupBy(array, groupOf) {
var groups = {};
array.forEach(function(element) {
var groupName = groupOf(element);
if (groupName in groups)
groups[groupName].push(element);
else
groups[groupName] = [element];
});
return groups;
}
var byCentury = groupBy(ancestry, function(person) {
return Math.ceil(person.died / 100);
});
What the code does is not very important.
The question is: the groupBy function has two different 'bodies', i.e. it does completely different things, as far as I can see. In the first instance, it does a lot of logic, but the second time it, first, has a different second argument (function(person) instead of groupOf, and, second, it just divides an array element property (which is the date of death of a person in an array of 39 people) by 100.
How can it be that the same function does different things? I do understand that
these two instances of the same function somehow cooperate, but what is the general principle of such cooperation?
Thank you!
The code below is not "redefining" groupBy. It is simply calling it:
var byCentury = groupBy(ancestry, function(person) {
return Math.ceil(person.died / 100);
});
The groupBy function receives a callback function as the second parameter (groupOf). You are there passing an anonymous function for that, which returns Math.ceil(person.died / 100);.
The first one
function groupBy(array, groupOf) {}
is a function declaration where the name of the function is groupBy and it is globally accessable.
While the second one
var byCentury = groupBy(ancestry, function(person) {});
is a funcion call. Here the returned value is assigned to a variable byCentury.
May be you got confused due to function(person) {}.
Note that in Javascript we have First Class Functions which means that functions are treated like any other variable. Therefore function is passed as argument to the function groupBy
I have two variable and one function.
<script>
function myfunction(a1,a2,a3)
{
alert(a1+a2+a3)
}
var fname="myfunction";
var fdata="data1,data2,data3";
</script>
I want to call function from variable values. like this
myfunction('data1','data2','data3')
I know how to call function from variable value.
window[fname](); //this call myfunction()
But don't know how to call function with multiple arguments from variable values?
Give me a solution if you can!
First, you don't have to use the name of a function to keep a reference to it. Just use the function directly:
var fname = myfunction;
Then you can call it:
fname('whatever');
To pass parameters from that string, you'll have to get them out of the string, a process that will depend on how you've combined the values into a string in the first place. In your example, you could split the string on commas to create an array, and then use .apply()
fname.apply(null, fdata.split(','));
The .apply() method accepts an array as the second parameter (the first is a value to be used for this), and then calls the function such that the values of the arguments are the elements of the array.
Just add the arguments between the parentheses
window[fname]('data1', 'data2', 'data3');
To pass dynamically the arguments by using the fdata value, you should use apply (like #Pointy suggests).
window[fname].apply(null, fdata.split(','));
you can modify your code to be something like this maybe:
<script type="text/javascript">
function myfunction(a123) {
// remove the coma if you don't want it.
var completeData = a123.replace(/,/g, "");
alert(completeData);
}
var fname = "myfunction";
var fdata = "data1,data2,data3";
window[fname](fdata);
</script>
I hope it helps.
Lets consider this example:-
function X(){
var Y = function(arg1,arg2){
document.write(arguments.length);
document.write(arg2);
};
Y(arguments);
}
x(1,2,3,4,5);
/*Outputs 1 and undefined respectively.
Because here i am actually passing an array like-object to Y. */
By using apply here i am getting the desired results.
function X(){
var Y = function(arg1,arg2){
document.write(arguments.length);
document.write(arg2);
};
Y.apply(this,arguments);
}
x(1,2,3,4,5) //outputs 5 and 2
I want to create an apply like method that takes an Array of argument and invoke that function by passing arguments as seperate parameter values.
Like:
var arr=[1,2,3,4];
Y.apply_like_method(arr);
//and returns like Y(1,2,3,4)
Given this code:
var arr=[1,2,3,4];
Y.apply_like_method(arr);
//and returns like Y(1,2,3,4)
To make that work:
Function.prototype.apply_like_method = function(args) {
return this.apply(this, args);
}
Disclaimer: For illustration purposes only.
In other words, there's no way around .apply().
Just for shits and giggles using eval.
function myApply(fun, ar){
var i, r = [];
for(i=0; i<ar.length; ++i)
r[i] = 'ar['+i+']';
eval('fun('+r.join(',')+');');
}
You want to use the call method instead. See the MDN. What you are describing though is a hybrid of the call method and apply method; you want the ability to supply parameters individually, but to supply them to the function as an array. That, to my knowledge, doesn't exist currently and it would be easier to use apply/call as it was originally intended, or use a javascript object to pass the params into the function.
Sorry if this has been answered already, but I could not find an appropriate answer on here.
I've started writing my javascript code in a modular style lately and I have a question regarding how module variable scope works.
The following code gives me a conflicting answer.
I have a module named Base that declares two strings and an array. It also has a function called fetchData that uses the jQuery getJSON shortcut to set these variables with server data. Unfortunately when I ask for Base's string1 or string2, I get undefined. I understand that this is probably due to the fact that I have it set their values two functions deep (inside the AJAX callback and inside fetchData) and the scope limits it from seeing Base.string1 and Base.string2.
However, when I look at Base.array1 from outside the module, it's set to the appropriate data I pulled from the server, even though it's set from the same scope as the strings.
Here's the code:
namespace.Base = (function(){
var string1, string2, array1 = [];
function fetchData(){
$.getJSON('backendScript.php', function(data){
string1 = data.string1;
string2 = data.string2;
arrayCount = data.arr.length;
for(var i = 0; i<arrayCount; i++){
array1[i] = data.arr[i];
}
})
}
return{
fetchData: fetchData,
string1: string1,
string2: string2,
array1: array1
}
})();
If I change
string1 = data.string1;
to
namespace.Base.string1 = data.string1;
it works like I want.
So my question is, why is array1 set correctly when it's set from the same scope as the strings?
Also, what is the remedy for setting module-level variables from within the module's functions without having to give a global path (e.g. namespace.Base.string1)?
The problem is that you actually have two different references, the variable string1 within the closure of the anonymous function that you invoke to create namespace.Base, and namespace.Base.string1, which is on the object returned from that anonymous function. Your assignment of the variable string1 to the object property string1 is a one-time set, not a live reference. Further modification of the variable string1 will not affect the object property. Here's what you want:
namespace.Base = (function() {
var my = {
string1: null,
string2: null,
array1: [],
fetchData: function () {
$.getJSON('backendScript.php', function(data){
my.string1 = data.string1;
my.string2 = data.string2;
var arrayCount = data.arr.length;
for (var i = 0; i < arrayCount; i++){
my.array1[i] = data.arr[i];
}
});
}
};
return my;
})();
Now the local, but public, members of namespace.Base are in the object my. You can create private variables using var within the anonymous function, or create more public properties by adding them to my.
I would be a good idea to get familiar with closures and how they work:
How do JavaScript closures work?
Your "scope" issue is not actually a scope issue. The issue is that arrays are pointers to their data, strings are not.
namespace.Base is set to the results (returned value) of the anonymous function. -- It is set to be an object containing a function ref (fetchData), two empty strings and an array.
If you later call the fetchData function, then it will change the contents of array1.
But it will also create two new strings (from data.string1 and data.string2). The old values of string1 and string2 (which are namespace.Base.string1 and namespace.Base.string2) are not changed. So they are left as empty strings (not what you want).
Example of this. Try it in Firebug--
s1 = "Hi";
s2 = s1; // s2 => "Hi"
s1 = "Bye"
alert(s2); // *** s2 is still "Hi", it was not changed!
// But arrays are different:
a1 = ["Hi"];
a2 = a1;
a1[0] = "Bye";
alert(a2[0]); // a2[0] is now "Bye"
Added: Asynch Timing error
Also, note that your code is wrong as written since you're not giving the caller any way to know when the Ajax call has completed:
namespace.Base.fetchData(); // starts the Ajax call via getJSON method
var a = namespace.Base.array1; // ERROR!! The value of namespace.Base.array1 is
// indeterminate since you don't know if the
// the Ajax request has completed yet or not!
You appear to be trying to convert the asynchronous Ajax call (which invokes a callback function once the answer has been received from the remote server) into a synchronous call which will not return until the results have been received.
This is a really bad idea. (If you want to know more, ask another question in SO.)