What is the difference between JavaScript class definitions styles? - javascript

I am not clear on the actual difference between these two styles of "class" definitions in JavaScript.
Method a:
function myclass() {}
Method b:
myclass = function() {}
Is there any difference?

Those are functions, the first one is a function declaration, the second is a variable assignment with a function expression.
The main difference is that the function declarations are hoisted up in the current scope at parse time, they behave like if you declared them at the top of its enclosing scope.
The grammar of both is very similar, the only grammatical difference is that the name function expressions is optional, the parser knows which one you are using based on the "context" where you use it, e.g. your first example is a function declaration because the function itself is defined on a Program (technically a place outside of any function, in the global scope), or in FunctionBody (inside a function).
A function expression is created when it is evaluated itself in expression context, e.g.:
function foo () {} // function declaration
(function foo() {}); // function expression
In the above example the second one is interpreted as a function expression because is surrounded by parentheses, and parentheses can only hold expressions...
I highly recommend you the following in-depth article about the topic:
Named function expressions demystified

The latter is a closure which you are assigning to a variable. As soon as the variable is deleted (or is assigned a different value) you won't be able to call the function anymore. Besides that both are pretty much the same as functions are first class citizens in Javascript.

Firstly, you're defining functions, not classes.
Secondly, the second definition will put the myclass into the global namespace, whereas the first will not (it would be defined in function scope instead). However, so far as I'm aware, the following are roughly equivalent:
function myclass() {}
and
var myclass = function() {}
There are some small differences, which are explored over on developer.mozilla.org. Having said that, I've never noticed any of the differences.

In the second case, you are declaring the function as a variable. It is particularly useful for something like this in OOP:
var myObject = new Object();
myObject.add = function(a,b) {
return a + b;
};
myObject.add(1, 2);

Related

What's the point of function expressions, they seem useless

I'm sorry if this is a duplicate, I have read a few posts asking this question but I haven't found a satisfying answer. I am new to JS, I have worked with C and Java. I recently learned about function expressions which, as far as I understand it, are anonymous function declarations that are assigned to some const variable. I don't see what the motivation behind this is/what the possible use of this is/ how could this ever do something you couldn't just do with a function declaration. for example
const example = function (input){
return 'Am I useless?:' + input;
}
console.log(example('Idk'));
Like this is just like calling a declared function with the same variable, but instead I'm using this variable name (example), which also makes the anonymous function seem pseudo anonymous since it does have a name it can be reference by.
I don't see when this would ever preferable over just a function declaration, yet the CodeCademy course I'm taking repeatedly uses the function expression thing, so I must be missing something.
I really appreciate the help/clarification.
TL;DR: No, function expressions aren't useless.
First of all, I would derive the function declarations from function expressions, not inversely. Function declarations are also useful, but they can be replaced by function expressions entirely.
The main difference: function declarations always create variables, while function expressions do not. However, you can still assign them to variables.
The following codes are identical (OK, not perfectly identical, they differ in their hoisting rules):
function foo(bar){
return 'baz'
}
//Function declarations create variables like how `var` does
var foo = function foo(bar){
return 'baz'
}
However, function expressions become handy when you don't want to store the function into a varā iable.
Examples include:
Constant functions:
const foo = function foo(bar){
return 'baz'
}
Block-scoped functions:
{
let foo = function foo(bar){
return 'baz'
}
}
IIFEs (Immediately Invoked Function Expressions):
(function (bar){
//Here we have an encapsulated local scope and the ability to return things
return 'baz'
})('foo')
Callbacks:
asyncFn(function (){
console.log('Done!')
})
Storing in objects:
foo[2].bar = function (){
return 'baz'
}
Assigning to previously declared variables:
let foo = null
console.log(foo)
foo = function foo(bar){
return 'baz'
}
And, although technically all of the above can be solved by using function declarations only, that would result in lots of unnecessary variables and harder-to-read code.
I don't exactly know why Code Academy prefers to use function expressions in your case, but I think that the point is in the const keyword, as it is:
Block-scoped
Constant
Restricts strange quirks that var (and function declarations) would allow
Hoisted with temporal dead zone (cannot be accessed before it is declared)
Functions are first-class objects in JavaScript. In your programming background from Java or C this is not true.
A use case for storing a "function" in a variable is to pass it somewhere else - e.g. as a callback. In Java you could compare it to a Runnable, but still it is a different concept.
Javascript is crazy if you come from a "proper" programming language! :) Watch that talk by Brian Leroux for some crazy fun.. https://www.youtube.com/watch?v=et8xNAc2ic8

Any difference between f() and (f())?

Any difference between
var myfunc = (function () { return function () { ... } }());
and
var myfunc = function () { return function () { ... } }();
Is it just a matter of style or is there more to the surrounding () in the first form?
Nope. Or at least not in your example.
The outer parens only matter when the function keyword would be the first token in a statement.
// cool
var foo = function(){}();
var foo = (function(){}());
// also cool
(function(){}());
// not cool, syntax error
// parsed as function statement, expects function name which is missing
function(){}();
// also not cool, syntax error
// declares a function, but can't be executed immediately
function foo(){}();
When function is the first token in a statement, it's a function declaration (think named function), which behaves slightly differently than function in all other contexts. That leading paren forces the parses to treat it like a function expression (think anonymous function) instead, which allows immediate execution.
See: What is the difference between a function expression vs declaration in JavaScript?
If you start the line or statement with something else, like variable declaration, it technically doesn't matter at all.
No difference, though Crockford advises the use of the former, to ascertain that it's being treated as a function expression.
For more info, read these:
Immediately-Invoked Function Expression (IIFE)
Named function expressions demystified
There's no technical difference, It's just an idiomatic style used for readability to signal at the start that it's a self-invoking function.
no difference, it is just a matter of style. Both are executed functions and they return whatever they return in the variable and they are returning a function. check this out
the purpose is to avoid the global scope, adding the var myfunc = in front of (function (){ return function(){}}()); essentially defeats the purpose
compare the two
(function(){...do something...}());
this function is ran in a local scope, which is inside the parentheses.
var myfunc = function(){};
this function is ran on the global scope.
why not this way, because you can get your self into naming conflicts with other methods and var as well as plugin's named var and it can hinder your applications performance with the var being saved on the global scope.
I perfer
(function() {})();

Is this an anonymous function?

In the first snippet below, based on my understanding I am creating a function and assigning it to a variable. But does that mean the function will take that name of the variable ?
var aFunc = function(){};
I know this is named function.
function bFunc(){};
So, first of all we have to clarify the main difference between the two functions you wrote.
This one:
var aFunc = function(){};
is a function expression. Where this one:
function bFunc(){};
is a function declaration.
In a function expression you're using the function operator to defines a function inside an expression.
When you declare a function you're using the function statement.
At the beginning it can be confusing because they're really similar, however function declaration and function expression behaves differently. First of all, you can't declare a function that is anonymous: if you're using a function statement, the name is mandatory.
So only functions defined with the function operator can be anonymous:
var aFunc = function(){};
That's an anonymous function. In some browsers you can actually print the function's name and see by yourself:
console.log(aFunc.name);
(Notice that this is not standard yet, but there is a proposal)
But it doesn't means that functions declared with the function operator have to be anonymous. For instance:
var aFunc = function myFunction() {};
It's a named function. However, that's still different from having a function declaration like that:
function myFunction() {};
var aFunc = myFunction;
Why? Because in case of function expression, you don't declare a myFunction function in the scope:
var aFunc = function myFunction() {};
console.log(typeof myFunction) // undefined, unless some bugs
So what's the point to give a name to a function expression? The answer is: to have access from that function from the function's body itself, without pollute the scope. Imaging for instance you want to add an event listener to a DOM node, but execute the listener only once:
document.body.addEventListener("click", function onclick() {
// do something
document.body.removeEventListener("click", onclick, false);
}, false);
So you don't pollute the scope with a lot of functions that you use only for purpose like that ones, and you can still have access to the function from the function's body. That's especially useful in ES5 where arguments.callee is deprecated, and for recursion.
Another difference between function expression is that you can invoke them immediately, but you can't do that for function declaration. So, for instance:
function() {
console.log('foo');
}();
Will throw an exception, because the engine can't understand if it's a function declaration or a function expression. But if you force the engine to look at it as an expression:
!function() {
console.log('foo');
}();
// or
(function(){
console.log('foo');
}());
// etc, there are a lot of ways
Here we are: JS understand is an expression, therefore threats the function as an operator and not as a statement. And you obtain the IIFE (Immediately-Invoked Function Expression), that are useful in a lot of scenarios, specially where you want to isolate code.
So, back to you question, why the name of this function:
var aFunc = function(){};
is not aFunc?
Because, it's an expression. So the value knows nothing about the assignment on the left. It's like having:
var aFunc = -3;
Where the - is the Unary Negation operation and the 3 is the value: they knows nothing about aFunc, right? It's exactly the same with function expression, where function is the operator, and (){} is the value.
No.
In the first example you are creating an anonymous function and then assigning it to "aFunc"
In the second example you declare a function and call it bFunc.
The most notable difference between the two is that you can't call "aFunc" until after the line where you assign it.
No, the function will not "take the name of the variable". The variable will hold a reference to an anonymous function. The function itself is still anonymous.
Note that this makes little difference in the end though, this function reference can be treated exactly the same as any regular named function once it's assigned. In fact, it makes so little difference, a named function can be treated like a variable holding a function reference too:
function foo() { }
foo();
foo = 'bar';
alert(foo); // bar
The term "anonymous function" is jargon, so likely what it means will change over time. There is no specification that states what it is, so it can be whatever you want it to be. And whatever you decide will likely be disputed by someone else. Jargon is like that (look up the word "trunking", a common jargon term in telephony).
Strictly, there are function declarations where the name is mandatory, e.g.
function foo() {
...
}
and function expressions where the name is optional. If the name is missing, e.g.:
var x = function () {
...
};
then that, to me, is an anonymous function. If it has a name, e.g.
var x = function foo() {
...
};
then it's a named function expression (and not an anonymous function). From my perspective, any function expression without an optional name is an anonymous function. There are many uses for function expressions, e.g.
// assignment to a variable
var x = function() {...}
// pass as a parameter
foo(function(){...})
// immediately executed and pass the result
foo( (function(){...}()) )
and so on. So in the OP, the right hand side of the assignment is a function expression with no name so to me, that's an anonymous function. The fact that it's then assigned to an identifier doesn't suddenly make it a named function expression.
Others may differ of course.
Incidentally, the results of:
function foo(){}
and
var foo = function(){};
are practically indistinguishable, the main difference is when the functions are created.
No it is not. The right hand side of your first statement is a Function Expression. It is anonymous as long as you don't assign it to a variable.
After you have assigned it, you can use it as a declared function.
See more details about function declarations in this question

js pattern problems

I'm confused by a javascript design pattern I'm reading about:
var class = (function() {
...a bunch of code...
return {
.. some more code..
;
// or, in some cases
return function(constructorArgs) {
};
})();
My question is: What is the return statement doing? Why is it there? I'm confused because no-one wants to mention it or talk about it.
There's two distinct patterns that you're mentioning, I think.
Anonymous Closures
The first is using an anonymous function to wrap a block of code in order to create a closure:
var outer = (function() {
var inner = "now you see me!";
return inner + " now you don't"
})()
The anonymous function creates a new scope for var-defined variables. In effect, this allows you to define variables that are only visible within that particular function.
In the example above, you have access to inner within the function, but it is not defined outside of it.
"Classes"
The second is a common pattern for defining "classes" in JavaScript:
var MyClass = (function() {
function MyClass(arg) {
this.arg = arg
}
return MyClass
})()
By defining the constructor function within a closure, you can be sure that your class is well contained. It also enables you to share class-wide state or private helper methods without polluting the global namespace, or resorting to placing them as properties on your class constructor's prototype.
the code to the right of the = symbol is of this form: (function(){})(); What this does is compile a function - effectively the same as the following:
function temp() {
}
class = temp();
Inside the function in your example, however, there is another function being returned. What this means is that class is now also a function - the class function can then reference all of the variables etc. that are declared in the temp function, due to the closure effect referenced by vtortola.
The idea of this is to allow the inner function to refer to some state that you don't want to have hanging around in your "global" (or semi-global) scope - it doesn't matter where the class method is called, or who by, it will always have access to that data.
Edit: It appears from the code that the purpose of the pattern in this case is to create a "class" type function - so then you'd be able to call it with the following code:
var myInstance = new class();
Though I've a feeling that none of the code will work as I'm reasonably certain that class is a reserved word...
This is called a closure.
var myVar = (function (param1, param2){
//do things
}('myParam1','myParam2')):
The javascript engine will immediatly execute what is between the parenthesis.
And the value of myVar will be what the function function (param1, param2){ ... } returns.
This function will use ('myParam1','myParam2') as arguments.
You can write closure in two different ways :
(function (receivedArgs){
//do things
})(yourArguments);
or
(function (receivedArgs){
//do things
}(yourArguments));
It is a closure. A function is returning an inner function enclosing some variables in the middle.
https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Closures
Cheers.

Javascript: explain this syntax to me

JS newbie here, I've been looking through some code recently which uses syntax I'm not too familiar with. Here's an example, followed by my questions:
function Group(args) {
this.showItem = showItem;
function showItem(args) {
...
}
}
var group = new Group (args);
Questions:
As I understand it creating function Group and then instantiating via group = new Group is essentially prototypal equivalent of defining a class and then instantiating an object of that class. Is that correct?
Regarding the properties (methods?) of Group, what is the above syntax for showItem called? Why not just define it like:
this.showItem = function(args){...};
Would changing the code to the above change any different behavior?
If you did define it as above, what is that syntax called?
The Group function is being used as a constructor; your intuition is basically correct.
There is no good reason not to use an anonymous function expression like this.showItem = function(args){...};, unless you wanted to reuse the local variable showItem.
I'm not sure which syntax you mean. The function(args){...} is an anonymous function expression, and the this.showItem is referring to a member of the object this. Taken all together, I suppose you could call it "setting a member function of an object".
Bonus tip (which maybe you already knew?): the reason you can use showItem before its definition is due to function hoisting.
EDIT:
You seem to be asking about function expressions versus function declarations as well as named versus anonymous functions. The primary differences are:
Function declarations always stand on their own. They are never part of another operation, e.g. assignment. Your first example uses the function declaration function showItem(args) {...}. Function expressions are used as an expression in some operation (e.g., assignment, passed as an argument, etc.). Your second case uses a function expression.
Function declarations are hoisted to the top of the current function scope, so showItem in your first case is defined and contains the function when you use it in your assignment operation. Function expressions are not hoisted.
Function declarations are always named. Function expressions may be named or anonymous. When a function is defined with a name, that name is accessible as the name property of the function object. A function's name is immutable and independent of any variables that hold a reference to the function. Also, code inside the function body can refer to the function by its name as a local variable (which is sometimes useful for recursion inside named function expressions).
To review:
Function definition: function showItems(args){...};
Anonymous function expression: this.showItems = function(args){...};
Named function expression: this.showItems = function showItemsName(args){...};
In the first case, there is a local variable called showItems defined and the definition of showItems is hoisted to the top. The difference between the latter two cases is that this.showItems.name will be "showItemsName" for the third case and undefined for the second. Also, showItemsName will be a local variable within the function body of the third function that holds a reference to the function object.
The Group function is used as a constructor. However, the way this is done is a bit inefficient. What this code is doing is creating a new function and attaching it to the constructed object. He may be doing this because he wants to create a closure (i.e. use a variable only present in the namespace of the constructor), but absent that reason it's better to do this:
function Group(args){}
Group.prototype.showItem = function(args) {};
This way the same showItem function is shared among all objects constructed by Group via the prototype chain.
The benefit of using the original code vs an anonymous function is that the function has a name--this is a great help in debugging because reading a traceback full of anonymous function calls is no fun! To expand, there are three types of things that use the function keyword:
Function declarations When at the top level of a program or a function (i.e., of something that creates/has its own namespace), you may declare a function with a name. (The name stays with the function object throughout the program and will appear in tracebacks.) This is function showItem(args) {} in your example. (Note that this is only a function declaration at the top level of a file or function. There's a very similar thing I'll get to last.) By convention most people seem to omit semicolons after these.
Function expressions When part of an expression (such as assignment, return, etc), it is a function expression. The identifier part of the function expression is optional, so these are both function expressions:
var myfunc1 = function(){};
var myfunc2 = function MyFunctionName(){};
The second form is called a "named function expression". The great benefit of using this form is that MyFunctionName is no longer an anonymous function--this name will be attached to the function and will show up in tracebacks (for example). However there is a very serious bug in JScript (IE <= 8) that makes using these problematic. Read the article I linked above for details.
Finally, there is a common extension syntax called function statements. These look exactly like function declarations, except they are not top level! For example:
function() {
function foo(){} // function declaration
if (1) {
function bar(){} // function STATEMENT--not standard JS!
}
}
You should not rely on this extension, but should do this instead:
function() {
var bar;
if (1) {
bar = function bar(){};
}
}
this.showItem = function(){} would be called a "function expression in an assignment", and the original code is just using a "function declaration".

Categories

Resources