I've noticed in Javascript there are 2 different ways to use functions:
Use the variable followed by a dot and then the function, like string.trim();
Use the variable inside the function, like parseInt(string)
What are the differences?
Are the one in point #1 not functions? How are they called?
I know inside parenthesis you can have more variables, but why is str.trim() and not trim(str)?
They are both functions, but I believe the first example in your question is normally called a method.
I'd encourage you to read the really useful Functions chapter of Eloquent Javascript. Just a couple of extracts that seem relevant:
A function definition is just a regular variable definition where the
value given to the variable happens to be a function.
and
A function is created by an expression that starts with the keyword
function. Functions have a set of parameters (in this case, only x)
and a body, which contains the statements that are to be executed when
the function is called. The function body must always be wrapped in
braces, even when it consists of only a single statement (as in the
previous example).
A function can have multiple parameters or no parameters at all.
I would also keep in mind that in JS almost everything is an object, or as someone else put it:
Since functions are objects, they can be used like any other value.
Functions can be stored in variables, objects, and arrays. Functions
can be passed as arguments to functions, and functions can be returned
from functions. Also, since functions are objects, functions can have
methods
Related
From this question, I found nested functions created each time the nesting functions get called as I expected. But the word 'create' doesn't make it clear about this question. Do Javascript engines have to interpret the definition of the nested functions everytime as well? I'm asking this question in wondering if the engines save the definition of a nested function somewhere and will return a function bound with some variables that are used in the nested function like below code does.
class A {
functionForInstance = this.sharedDefinition.bind(this);
sharedDefinition() {
return this.someField;
}
}
One more question
According to #Jose Marin's answer, engines create closures(instances) from saved function definitions. Then does it also apply to arrow functions?
Engines doesn't need to interpret the definition of the nested functions every-time.
Functions are read only object, then once defined they can be reuse any time.
You are pointing something that could confuse people. Function execution is control in the call stack, and you could find the same function being called several times and using different closure. But they all share the same definition outside of the call stack.
There may be a performance drawback when using nested functions, because each time the outer function is called, new closure for the nested function will be created. If working with objects, it could be fixed by defining the function on object prototype instead of nesting.
See this MDN article on closures for more info and examples.
I'm brand new to JavaScript and currently learning about writing functions shorthand. I just came across this while studying:
const groceries = (groceryItem) => ' - ' + groceryItem;
Is it acceptable/best practice in the real world to write functions like this? (no return, no brackets) I notice that it may be annoying to expand upon. Or is this just standard practice?
I also notice shorthand if statements that have no brackets as well. Also standard practice?
I want to learn good habits early on, so any advice on this matter would be greatly appreciated.
There are several ways to declare functions and there are use cases and pros and cons to each. As a result, there is no "preferred" way. Use the appropriate syntax for your situation.
Below is a summary of the different ways to set up functions with a brief explanation of each. Click on the heading link to be directed to more in-depth resources on that type:
Function Declaration:
function foo(){
}
With a function declaration, the entire function is hoisted (regardless of it's actual location in the code) to the top of the enclosing scope. This makes it possible to invoke the function prior to its declaration point.
Function Expression:
var foo = function(){
}
Function expressions are just variable declarations that assign a function (as data) to the variable. As with function declarations, there is hoisting here too, but only the variable (foo in this example) declaration gets hoisted, not the assignment, so in this case you could not invoke the function prior to its declaration.
Arrow Functions:
const groceries = (groceryItem) => ' - ' + groceryItem;
This is simply a short hand syntax instead of using a function expression. However, there is a difference with an arrow function. With Arrow Functions, the object that this binds to is not affected within the function, while it is affected in a non-arrow function.
Immediately Invoked Function Expression:
(function(){
})();
An Immediately Invoked Function Expression (IIFE) is an anonymous function (a function with no name) that is turned into an expression by wrapping it with parenthesis and then immediately invoked with another set of parenthesis. This syntax is very common in JavaScript and is used to create a scope that doesn't conflict with other scopes.
NOTE:
Functions are the work horses of JavaScript, depending on how you set them up and invoke them, they do many different things:
They can be units of directly invocable code.
They can be the value of a variable or property.
They can be constructor functions that are used to instantiate Object
instances.
They can be raw data that is passed around via arguments.
Yes, I think this is considered acceptable, since arrow functions were specifically designed to allow it. One of the features of arrow functions is that they allow very simple functions to be written as one-liners like this. When you can calculate the return value as a single expression, you don't need to write the body with braces around it or the return statement explicitly. This makes traditional functions needlessly verbose, with more boilerplate than the actual code of the function. The traditional alternative would look like:
const groceries = function(groceryItem) {
return ' - ' + groceryItem;
}
This isn't so bad when defining a named function, but when you're using an anonymous function as a callback, all that verbosity may obscure the intent. Compare:
newarray = oldarray.map(function(x) {
return x * x;
}
with:
newarray = oldarray.map(x => x * x);
Arrow functions are a recent addition to the language, so I think we can assume that the design was given significant consideration. If the Javascript community didn't feel that shorthand functions like this were a good idea, they wouldn't have been allowed in the first place.
The function you wrote is what is commonly known as a "arrow function". They can prove very useful when you get to a somehow more advanced level in JavaScript and there is absolutely nothing wrong with them. On the contrary. Very commonly used with "higher order functions" for arrays, to give an example.
This SO answer elegantly explains how a "function with multiple parentheses" like the one below works:
myFunction(3)(4)
But I'd like to google it and read more about it. Does this way of constructing a function have a name?
There is no such thing as a "function with multiple parentheses".
However, you can write a function that returns a function. So you pass arguments to your function with 1st parentheses, get a function in return, and pass arguments to the returned function with 2nd parentheses.
This is mainly used for IIFE when combined with closure. This technic is also called currying, as suggested by #CRice.
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:
Explain the encapsulated anonymous function syntax
(10 answers)
Closed 8 years ago.
In the YUI library examples, you can find many uses of this construct:
(function() {
var Dom = YAHOO.util.Dom,
Event = YAHOO.util.Event,
layout = null,
...
})();
I think the last couple of parentheses are to execute the function just after the declaration.
... But what about the previous set of parentheses surrounding the function declaration?
I think it is a matter of scope; that's to hide inside variables to outside functions and possibly global objects. Is it? More generally, what are the mechanics of those parentheses?
It is a self-executing anonymous function. The first set of parentheses contain the expressions to be executed, and the second set of parentheses executes those expressions.
It is a useful construct when trying to hide variables from the parent namespace. All the code within the function is contained in the private scope of the function, meaning it can't be accessed at all from outside the function, making it truly private.
See:
http://en.wikipedia.org/wiki/Closure_%28computer_science%29
http://peter.michaux.ca/articles/javascript-namespacing
Andy Hume pretty much gave the answer, I just want to add a few more details.
With this construct you are creating an anonymous function with its own evaluation environment or closure, and then you immediately evaluate it. The nice thing about this is that you can access the variables declared before the anonymous function, and you can use local variables inside this function without accidentally overwriting an existing variable.
The use of the var keyword is very important, because in JavaScript every variable is global by default, but with the keyword you create a new, lexically scoped variable, that is, it is visible by the code between the two braces. In your example, you are essentially creating short aliases to the objects in the YUI library, but it has more powerful uses.
I don't want to leave you without a code example, so I'll put here a simple example to illustrate a closure:
var add_gen = function(n) {
return function(x) {
return n + x;
};
};
var add2 = add_gen(2);
add2(3); // result is 5
What is going on here? In the function add_gen you are creating an another function which will simply add the number n to its argument. The trick is that in the variables defined in the function parameter list act as lexically scoped variables, like the ones defined with var.
The returned function is defined between the braces of the add_gen function so it will have access to the value of n even after add_gen function has finished executing, that is why you will get 5 when executing the last line of the example.
With the help of function parameters being lexically scoped, you can work around the "problems" arising from using loop variables in anonymous functions. Take a simple example:
for(var i=0; i<5; i++) {
setTimeout(function(){alert(i)}, 10);
}
The "expected" result could be the numbers from zero to four, but you get four instances of fives instead. This happens because the anonymous function in setTimeout and the for loop are using the very same i variable, so by the time the functions get evaluated, i will be 5.
You can get the naively expected result by using the technique in your question and the fact, that function parameters are lexically scoped. (I've used this approach in an other answer)
for(var i=0; i<5; i++) {
setTimeout(
(function(j) {
return function(){alert(j)};
})(i), 10);
}
With the immediate evaluation of the outer function you are creating a completely independent variable named j in each iteration, and the current value of i will be copied in to this variable, so you will get the result what was naively expected from the first try.
I suggest you to try to understand the excellent tutorial at http://ejohn.org/apps/learn/ to understand closures better, that is where I learnt very-very much.
...but what about the previous round parenteses surrounding all the function declaration?
Specifically, it makes JavaScript interpret the 'function() {...}' construct as an inline anonymous function expression. If you omitted the brackets:
function() {
alert('hello');
}();
You'd get a syntax error, because the JS parser would see the 'function' keyword and assume you're starting a function statement of the form:
function doSomething() {
}
...and you can't have a function statement without a function name.
function expressions and function statements are two different constructs which are handled in very different ways. Unfortunately the syntax is almost identical, so it's not just confusing to the programmer, even the parser has difficulty telling which you mean!
Juts to follow up on what Andy Hume and others have said:
The '()' surrounding the anonymous function is the 'grouping operator' as defined in section 11.1.6 of the ECMA spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf.
Taken verbatim from the docs:
11.1.6 The Grouping Operator
The production PrimaryExpression : ( Expression ) is evaluated as follows:
Return the result of evaluating Expression. This may be of type Reference.
In this context the function is treated as an expression.
A few considerations on the subject:
The parenthesis:
The browser (engine/parser) associates the keyword function with
[optional name]([optional parameters]){...code...}
So in an expression like function(){}() the last parenthesis makes no sense.
Now think at
name=function(){} ; name() !?
Yes, the first pair of parenthesis force the anonymous function to turn into a variable (stored expression) and the second launches evaluation/execution, so ( function(){} )() makes sense.
The utility: ?
For executing some code on load and isolate the used variables from the rest of the page especially when name conflicts are possible;
Replace eval("string") with
(new Function("string"))()
Wrap long code for " =?: " operator like:
result = exp_to_test ? (function(){... long_code ...})() : (function(){...})();
The first parentheses are for, if you will, order of operations. The 'result' of the set of parentheses surrounding the function definition is the function itself which, indeed, the second set of parentheses executes.
As to why it's useful, I'm not enough of a JavaScript wizard to have any idea. :P
See this question. The first set of parenthesis aren't necessary if you use a function name, but a nameless function requires this construct and the parenthesis serve for coders to realize that they've viewing a self-invoking function when browsing the code (see one blogger's best-practices recommendation).