How to pass value into function that is a parameter - javascript

Hello I've come across this piece of code and I have no idea how it works.
function firstFunction(something, else){
//stuff being done
return something;
}
var myFunction = firstFunction(function(a,b){
return a*b;
},'car');
So I am fairly new to Javascript so I'll just say it is, a really confusing language. I understand I am declaring a variable that is assigning the firstFunction to itself and passing some noname function as first parameter and a String as a second one.
How do I go about passing the arguments into that noname functions?

Yes, your assessment is pretty much correct, although the code has a syntax error because you can use else as an identifier. These are referred to as anonymous functions.
Function in JavaScript can be used as parameter values or return values just as easily as any other value. This is what makes them first-class citizens of the language.
The anonymous function you pass in to firstFunction is returned and assigned to myFunction so if you want to call it, you can simply do this:
var result = myFunction(4, 5); // 20

Related

Executing a method inside a method

I'm currently working on a JavaScript exercise in FreeCodeCamp, and one of the test-cases my code should work with is a function call that looks like this:
addTogether(2)(3);
here is the bare-bones function I'm given:
function addTogether() {
return;
}
When I run the code below:
function addTogether() {
return arguments;
}
In the console, that the editor provides, I get:
TypeError: addTogether(...) is not a function
The instructions hint at using the arguments object, and it works well with test-case function calls that only have one argument object (i.e. addTogether(2, 3);), but not with the one I've shown above.
Is there a way to access/utilize the separate argument objects when they're in the format I showed above?
Note: I don't want any sort of answer to solve the problem, just info on any techniques on accessing the arguments of these type of function calls.
Help, is greatly appreciated.
Don't think of it as two separate sets of arguments. Think of it as you're calling another function (which you are). Functions are first-class values in JavaScript so you can use them just like any other value. This includes returning them from functions.
var f = function(y) {
console.log('f:', y);
};
var getF = function(x) {
console.log('getF:', x);
return f;
};
getF(1)(2);
Functions can also use values that exist in any parent scope. Loosely speaking, functions which do this are called closures.
function createGetX(x) {
return function() {
// Since x is in the parent scope, we can use it here
return x;
}
}
var one = createGetX(1);
console.log(one()); // Always
console.log(one()); // returns
console.log(one()); // one
Sometimes it helps me to think in a certain order. You can read the code "addTogether(2)" and stop before reading the "(3)".
From there you can see the exercise wants you to have that first part "addTogether(2)" return a function...since anytime there are "()" that means a function is getting called.
So "addTogether(2)" needs to return a function that takes one argument. Later that 3 will be one example of an input.
I think the name "addTogether" is a bit confusing..since that function's job is to make up and return the actual function that adds.
Sort of hard to explain this one without helping too much, but the bulk of your job here is to return a custom function, which includes the first variable (from it's scope) and expects another variable when it's called.
You could do this with closures.
function addTogether(x) {
return function(y) {
return x+y;
}
}

Passing "extra" arguments to a function stored in a variable - Javascript

I'm new to Javascript, I'm self-teaching, so this might be an obvious area, but no matter how I phrase the question I can't really seem to get my head around this one issue. At the moment I'm reading through http://eloquentjavascript.net/chapter6.html (which was on mozilla's MDN). I've come across this a couple of times now, I would just like a simple break down if possible.
function negate(func) {
return function(x) {
return !func(x);
};
}
var isNotNaN = negate(isNaN);
show(isNotNaN(NaN));
I don't understand how at the very last step isNotNaN (a variable) is passing an 'extra argument' (NaN) to the function stored in isNotNaN (negate(isNaN). "show(isNotNaN(NaN));"
I came across this same problem when the concept of enclosure was trying to be explained. But I don't get where this argument "NaN" is going in the above function, as it seems to me like the last statement ends up something like:
show(negate(isNaN, NaN));
I would be happy to provide more details. This concept of passing an extra argument to a variable already holding a function with an argument confuses the hell out of me!
There's no "extra" argument. The negate() function itself returns a function defined as a function expression, which can then be called with any number of original (not extra) arguments passed. A closure is used for the returned function to keep a reference to isNaN as func.
var isNotNaN = negate(isNaN);
At this point, isNotNaN contains a reference to the function
function(x) {
return !func(x);
};
Again, func here refers to the isNaN argument passed to the negate function, which is the immediate parent in the scope chain. The result is similar, but not the same as
var isNotNaN = function (x) {
return !isNaN(x);
};
The reason it is not the same is, if we change the value of isNaN, the behaviour of this function will change. In the example you posted, however, the value of func is equal to the original value of isNaN and cannot be changed by anything outside of its scope thanks to the closure.
Essentially, you can pass in any function and get a new function that returns the negated result of the original function in return. For example:
var isNotArray = negate(Array.isArray);
isNotArray(12);
//-> true
In fact, negate(isNaN) simply return a function to the variable isNotNaN. This function take a parameter (named x in your case), then execute the function isNaN on the parameter before negating it and returning the result.
Perhaps this example can clear some things out for you regarding closures:
function foo(x){
function bar(y){
return x+y;
}
return bar;
}
var fooRef = foo(1); // fooRef references foo() with x set to 1
console.log(fooRef(2), foo(1)(2)); // 3, 3
http://jsfiddle.net/ePwy8/

Execute private function inside the class by its name (string)

At the moment I have simple JavaScript class like this:
function MyClass() {
// ... some code ...
this.Create = function() {
funcName = 'myTestFunc()';
cTimer = setTimeout(funcName, 1000);
}
// ... more code ...
var myTestFunc = function() {
alert ('everything\'s OK!');
}
// ... more code ...
}
and to test it I'm using this code:
x = new MyClass();
x.Create();
I have some troubles to execute this function by it's name. If I put just eval(funcName); instead of setTimeout call it works fine but can't figure out why it doesn't work this way.
Course, this is part of more complex code but rest of code is irrelevant to this problem.
My question is obvious - How to execute function by its name set as setTimeout function's argument? Is it possible?
Note: Making this function public (this.myTestFunc = ...) isn't an option!
Update:
funcName = "myTestFunc()"; is just an example. In real code it looks like funcName = getRandomEffectFunctionName();! It's just a random value.
Referring to the update:
Instead of setting:
var funcName = "getRandomEffectFunctionNeme()";
Thus, setting a reference to the function's name you should do
var funcRef = getRandomEffectFunctionNeme;
And set a reference to the function itself . Not only this avoids the issues setTimeout with strings has*. It also solves your closure issue since your code is structured in such a way the timeout has access to the function itself.
In your case, let's assume you have some functions that are filters, for example lowPass highPass and blur. In that case, instead of choosing a function name we would be choosing a function.
First, we store these functions in an array:
var filters = [lowPass,highPass,blur];
In JavaScript, functions are first-class objects, you can pass them around just like other objects.
Next, we'll get a random number
var chosen = Math.floor(Math.random()*3);//get a random number between 0 and 2
Finally, we'll choose the filter and invoke it
var filter = filters[chosen];
setTimeout(filter,1000);
( * just try debugging it, it basically invokes the compiler whenever ran and is painfully slow)
You just pass a function to setTimeout as a parameter, rather then a string, setTimeout(myTestFunc,1000) .
When calling Create it would have access to it anyway because they are in the same closure.
NOTE: This solution is only applicable if you can not pass the function name as a function reference, for example if you're integrating with code that is outside your control. Generally, when possible, you should pass a function reference since in JavaScript, all functions are objects.
Assuming that the timeout and the function are in the same closure your code is pretty close. The problem is that your eval call executes in the global context because it is in a timer. This means they are no longer in the same lexical scope.
You can however, grab a reference to the function by clever use of eval which you can later call in the setTimeout invocation.
var F=eval(funcName);// gain a reference to the function given the function's name
cTimer = setTimeout(F, 1000);
If you're using AIR or don't trust the functionName string you can do the following:
function Test(){
var functionContainer={
t:function(){
console.log("it's t");
}
};
this.callT=function(functionName){
var F=functionContainer[functionName];
console.log("F is:",F);
setTimeout(F,500);
}
}
(new Test()).call("t");
This is preferable since you are invoking setTimeout with a function's name and not a string. In general, using setTimeout with a string can have issues, it's hard to debug or maintain.

How do I pass a method through another method without it being called, and pass a variable object into it?

Sorry for my last question. This is the question with better formatting.
I have a method that I am passing a method through :
method("my_passed_method()")
function method(passed_method){
eval(passed_method.replace('()', + '(' + obj + ')' );
}
But this returns :
SyntaxError: missing ] after element list
I'm assuming this is just some simple JSON syntactical error.
I think you probably want this:
method(my_passed_method)
function method(passed_method){
passed_method(obj);
}
Note that when you're calling method, you're passing in a function reference, not a string, and you're not calling my_passed_method (there are no () after it), you're just referring to it.
Within method, you call the function via the variable passed_method, because that variable contains a function reference.
In JavaScript, functions are first class objects. Variables can refer to them, you can pass them around, etc.
Here's a complete, self-contained example:
// The function we'll pass in
function functionToPass(arg) {
display("functionToPass's arg is: " + arg);
}
// The function we pass it into
function functionReceivingIt(func) {
func("foo");
}
// Do it
functionReceivingIt(functionToPass);
Live copy | source
The name of a method, is at the same time, your reference to that method object. The parentheses, optionally with parameters in between them, make javascript call that method. This means your code can be rewritten to:
method(my_passed_method)
function method(passed_method){
passed_method();
}
So, what's going on here?
When you pass in the name my_passed_method, the javascript engine will look what that name maps to, and find that it maps to a functio object.
Than, inside the function call of method, that object is assigned to the parameter name `passed_method. Than, putting parentheses after this name will make javascript try to execute that object, which is indeed possible because this object is a function, and just like any other type, functions are what we call first class citezens. You can treat the just like any other value by assigning them to variables and passing them around.
In Javascript functions are considered objects. You may pass them as parameters to other functions, as demonstrated below.
function something(x){
alert(x);
}
function pass(func){
pass2(func);
}
function pass2(func){
func("hello");
}
pass(something); //alerts hello
Demo:
http://jsfiddle.net/wBvA2/
eval is evil; or so they say. You don't need to pass the function as a string you can just pass the function itself and then use Function.call or Function.apply to pass the argument (or just call it directly):
method(my_passed_method);
function method(passed_method) {
passed_method(obj);
// OR: passed_method.call(window,obj);
}
The circumstances where eval are necessary are very rare.
Note that your code will evaluate obj as javascript, so the outputs may differ.

Javascript function syntax needs explanation

return this.foo("abc",function(){
//do something
});
Can some one tell me what does the above line do?
THanks
It grabs a reference to this, which might be the DOM Window, a DOM element, or any other JavaScript object depending on how and where the above code is being run.
It (skipping ahead) prepares a new anonymous Function that //does something.
It attempts to invoke a method foo on object this, passing in two parameters "abc" and said anonymous Function.
Very often when you see code that passes along an anonymous function (e.g. function(){ ... }), it is in fact holding on to that function in order to execute it not right away but at some later point in time, such as in response to a click event or a timer.
It calls the function referenced by this.foo and passes two parameters: The string "abc" and an anonymous function function(){ //do something}. It then returns the result.
It is equivalent to:
var a = "abc";
var b = function(){
//do something
};
return this.foo(a, b);
Functions are first class objects in JS so you can pass them around like any other value.
I recommend to have a look at the MDC JavaScript guide.
looks like this.foo() is a function that returns something. so the return value is, what this.foo() returns.
calls an instance method that gets as parameters a string and a function.
It will return (yeah, like it is in English) the returned result of a function this.foo(...) (in the most simple form, ithe function this.foo(...) return "something" then the code will return "something"). The function this.foo("abc", function(){...}); is itself a function which receives 2 arguments: A string "abc" and a function(). The function this.foo will do something and return "something" to return by the main function.
[x]

Categories

Resources