I'm a total newbie in js, so please be gentle with me :)
I want to understand where can we use the dot operator on some variable (in this case - an array), and when we cannot.
consider the following code:
//example 1
function f1(x) {
return x*x;
}
console.log(map(f1, [1,2,3,4,5]));
console.log([1,2,3,4,5].map(f1));
//example 2
function f2(arr) {
return arr;
}
console.log(f2([1,2,3,4,5]));
console.log([1,2,3,4,5].f2());
I know the examples are rather different, but still - in example 1 both prints work (and print the same) - even when using the array.function(..) syntax, while in example 2 the second print raises an error.
basically, what is the difference between the two, and why does it work only in example 1?
and generally - can I apply this method over different variable types (numbers, booleans, etc.)?
In the first example your are using the Array.prototype.map() function.
This function can be called in 2 different ways (See the docs)
[1,2,3].map(function(x){ ... }): //In your case the callback function is *f1()*
OR
arr.map(callback, [1,2,3]);
The second example is not working because the class Array has not function called f2()
[1,2,3,4,5] is an instance of Array "class", and that "class" has map method, that's why the following is a valid code:
[1,2,3,4,5].map(f1)
map method can accept any function as a parameter, and you're passing in your f1 function. It will be executed inside map function and it's executed as a standalone function.
Array "class" doesn't have f2 method, that's why this is invalid code:
[1,2,3,4,5].f2()
Here, f2 is executed immediately and is a part of [1,2,3,4,5] object
In the first case, map is defined as both a global function and public function of the Array. You can therefore call it via map(arr) or arr.map(..)
In the second case, as you only defined f2 as a global function which means the array can't access it.
Related
i.e. is there any way to accommodate an argument, e.g. the string, if a function is invoked like so: foo('str') while written like so:
function foo(){
console.log(<the_argument>)
}
console.log(foo('str')) // <--- 'str'
You can use "arguments" keyword to get the arguments provided in foo('str'). For ex.
function foo(){
var arg = arguments; // contains array of arguments provided
console.log(arg[0]);
}
console.log(foo('str')); // prints "str"
You can use the arguments object to do the same:
function foo() {
if(arguments.length >0) {
return arguments[0];
}
}
console.log(foo('str'));
Additional info:
ES6 brings in Rest parameters & Spread syntax which help when working with functions
Arguments passed to a JS function can be retrieved by using the arguments array inside the function.
function func1(a, b, c) {
console.log(arguments[0]);
// expected output: 1
console.log(arguments[1]);
// expected output: 2
console.log(arguments[2]);
// expected output: 3
}
func1(1, 2, 3);
For more information please refer to the Mozilla documentation https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
Yes there is. There is an implicit arguments local variable. It is iterable and can be used like an array (although it isn't an array) to access all the function's arguments without relying on any formal parameters.
function foo()
{
for (i in arguments)
{
console.log(arguments[i]);
}
}
foo('str','wasdf',9)
See Arguments object, for a more detailed definition.
Obviously not. You can check your self. If you are in angular side then you have something call DI and you can have service injected.
But you can do like make variable outside and access inside a function. If you see fit, you can test it.
Actually, you can do it, check https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
In this article js log function, there is a statement:
Function.prototype.apply.call(console.log, console, arguments);
I'm really confused by this statement.
What does it do?
How can I analyse this statement?
Or with some thoughts or tools, I can figure it out step by step?
Can it be simplified to more statements to achieve the same result? for instance: var temp = Function.prototype.call(console.log, console, arguments); Function.prototype.apply(temp);
Thanks for the response.
Apply is a function on the function prototype. Call is also a function on the function prototype. Apply is a function, therefore, it has call on it's prototype. All this is doing is calling the apply function.
Read more about apply here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
What does it do?
It calls console.log with console as this during the call, passing along the arguments in the
pseudo-array arguments as discrete arguments to the function.
So if arguments had "hi", "there" in it, it would be the same as:
console.log("hi", "there");
How can I analyse this statement?
Or with some thoughts or tools, I can figure it out step by step?
Let's start with what the apply and call functions are: They each have the ability to call a function
using a specific this during the call and passing arguments to that function. apply gets those
arguments from a single array (or anything array-like). call gets those arguments as individual arguments.
Normally, you'd see apply or call used like this:
someFunction.apply(valueForThis, ["arg1", "arg2", "arg3"]);
// or
someFunction.call(valueForThis, "arg1", "arg2", "arg3");
The only difference between apply and call is how they expect to get their arguments (apply = in
an array-like thing, call = as individual arguments).
So why, then, isn't that code doing this?
console.log.apply(console, arguments);
It's being cautious: console.log is a function provided by the host. It may not be a true JavaScript
function, and so it may not have the apply property.
So that code is avoiding relying on console.log having the apply property.
Which is where Function.prototype comes in. It's a reference to the object that is the prototype of all true JavaScript functions.
That prototype is where the apply and call properties on JavaScript functions come from.
So if we're worried that console.log doesn't have it (e.g., in case it doesn't inherit from Function.prototype), we can grab apply from that prototype object directly.
So the code is using call to call apply, and using apply to call console.log.
Can it be simplified to more statements to achieve the same result?
Not really, there's not a lot we can separate. I'll try to use variable names to clarify:
var thisValue = console;
var functionToCall = console.log;
var applyFunction = Function.prototype.apply;
applyFunction.call(functionToCall, thisValue, arguments);
Let's take this one part at a time.
Function.prototype.apply, more commonly seen as myBigFatFunction.apply, lets you call a function with a different this context than it would normally have. The difference between apply and call is that the former takes an array of arguments, the latter takes direct arguments after the first. Example:
myStr.substring(5)
String.prototype.substring.apply(myStr, [5]);
String.prototype.substring.call(myStr, 5);
^ all equivalent
However, for reasons I can't fully explain myself, some browser-native functions accessible to JavaScript don't have this function as a property (eg, console.log.apply). It's still possible to manually call it in the same manner though; so that console is still this, when it calls log, and that's what the given function is doing.
The reason for all that complication is that they want to pass in the arguments special variable. This is a keyword that exists in all functions, which represents all arguments to the function as an array-like object (so, suitable for Function.prototype.apply)
Your variable suggestion would likely simply call console.log once with console as argument one, and arguments as variable two, and return the result, rather than give you a function in a variable. If you want a shortened reference, it's possible you could use Function.prototype.bind, but that could actually lengthen your code.
This question already has answers here:
Applying a Function to Null in Javascript
(5 answers)
Closed 7 years ago.
I am learning about call and apply in javaScript from a online TUT. This function allows more arguments to be passed, rather than having a fixed amount.
var calculate = function(){
var fn = Array.prototype.pop.apply(arguments);
return fn.apply(null, arguments);
};
What I am having difficulty wrapping my head around is this statement.
var fn = Array.prototype.pop.apply(arguments);
The presenter of the of the TUT, explained it as the following:
We are binding the apply method onto the arguments object. This is going to give us the Function Object and assign it to the fn variable. It will also remove the Function Object from the argumentsObject. Because the Array's pop method takes the final element in the array, it removes it from the Array and then assigns to what ever called the method. In this case the fn variable.
What confused me was the following:
We are binding the apply method onto the arguments object. This is
going to give us the Function Object
It will also remove the Function Object from the arguments
Object.
And when we write in the return statement:
return fn.apply(null, arguments);
Why are we including null?
Array.prototype.pop.apply(arguments);
When you have a function, there's automatically an arguments objects, which is an Array-like object of arguments. If you call this fake function:
someFunction('hello', 'world');
and someFunction looks like this:
function someFunction() {
console.log(arguments);
}
The console.log will output ['hello', 'world']. However, don't be confused... That is not an Array object! It is an "array-like" object. Therefore, you can't say arguments.pop()... because arguments doesn't have that method (it belongs to Array.prototype). However, normal Array objects do have access to Array.prototype (e.g. [1,2,3].pop() // => [1,2]).
When you say .apply(), the first argument is the context... It sets the this. So really, Array.prototype.pop.apply(arguments) is a clever way of mimicking arguments.pop(). But you can't do arguments.pop(), because it doesn't have a pop method.
In return fn.apply(null, arguments);, null is the first arguments because we don't need to set a new context for this example. arguments is the second arguments because it's being passed in to use with fn.
.apply() returns a function object, so it returns something like this:
function() { ... }
We can then later invoke that function.
By the way, .pop() mutates the original object (in this case, the array-like object arguments). So you're passing in arguments to fn, but it's missing the last item that was in it previously.
According to MDN:
Syntax
fun.apply(thisArg, [argsArray])
Parameters
thisArg:
The value of this provided for the call to fun. Note that this may not be the actual value seen by the method: if the method is a function in non-strict mode code, null and undefined will be replaced with the global object, and primitive values will be boxed.
argsArray:
An array-like object, specifying the arguments with which fun should be called, or null or undefined if no arguments should be provided to the function. Starting with ECMAScript 5 these arguments can be a generic array-like object instead of an array. See below for browser compatibility information.
The last argument passed to calculate is assumed to be a function. It is popped from the arguments list. (Using apply because arguments is not a real array.)
This popped function (fn) is called with the rest of the arguments list. (All other arguments passed to calculate). The arguments list no longer contains fn because pop() modifies the original object.
NULL is used because fn is called without a value for this. (See MDN)
If you call calculate for instance like
calculate(2, 3, function(a, b){ return a + b });
it will return 5.
I am reading the Eloquent JavaScript and I got to Functional programming (chapter 6). I am confused by the following example:
show(Math.min.apply(null, [5, 6]));
function negate(func) {
return function() {
return !func.apply(null, arguments);
};
}
*Note: The show() simply prints out the output to the console on the Eloquent JavaScript website.
I don't get how the negate() function is related to the code within show(). Where is the negate() function called? I don't see that it was used anywhere in that example, or am I wrong?
The code given contains two examples. Every function has an apply method. In the first example, Math.min's apply method is used to call Math.min with the argument list [5,6]. The second example should be viewed in contrast to the preceding example in which negate is defined as
function negate(func) {
return function(x) {
return !func(x);
};
}
In that example, negate(func) returns a new function of one argument that calls func with that single argument, negates the result, and returns it. What happens if func expects more than one argument, though? That's what this example covers.
function negate(func) {
return function() {
return !func.apply(null, arguments);
};
}
In this definition, negate(func) returns a new function of an arbitrary number of arguments that calls func with the list of provided arguments, negates the result, and returns it.
That part of the book was to explain that some functions take multiple parameters, so you must call the func parameter with .apply() instead of just func(x).
The first example used NaN, which accepts one parameter. That's why it worked to use:
return !func(x);
But some functions, like Math.min, accept several parameters. Technically, when using negate, you don't know what function will be passed, and what arguments will be passed. Therefore, you can't hardcode in x being passed to func. Using .apply(), you can pass the original arguments, arguments, to the func call.
Reference:
apply: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply
This question already has answers here:
Location of parenthesis for auto-executing anonymous JavaScript functions?
(4 answers)
Closed 8 years ago.
Difference between the two functions:
(function($){
console.log($);
}("test"));
(function($){
console.log($);
})("test");
I've tried it out on the web console and pressed 'Run'. They return the same thing. What exactly is the difference with the change of parenthesis location?
I am assuming that the second one is run immediately, right?
The two snippets are identical; neither function returns a value and both log their argument to the console. Similarly, both anonymous functions are called with the argument "test".
The only difference is in syntax, regarding the grouping of the function definition vs its application to its arguments. The first function groups the function definition along with the () operator, whereas the second function groups the function definition separately from its application.
Ultimately there is no semantic difference. Both snippets contain an anonymous function which logs its argument and is then called with the argument "test".
The only difference I can think of is if you assign a variable to a function inside the first set of parentheses, you will get different results, depending on the grouping.
var test;
(test = function(arg) {
console.log(arg)
})('I am the argument!')
That works as expected: It assigns 'test' to the function, then runs it once with the argument in the second set of parentheses. It's the same as setting test, then running it with test('I am the argument!')
But how about the other way?
var test;
(test = function(arg) {
console.log(arg)
}('I am the argument!'))
test is undefined! Why? Because when you put the parentheses right next to the function, it invokes the function before it then assigns it to the variable. If you wrap the assignment in parentheses then run it (example 1) then you're good to go.
There is absolutely no difference.
In first case you give "test" value to your function without scopes and there isn't making any difference. In both ways it will working in same way.