0

I've been seeing both types of code and I'm wondering if there is a preference; Using anonymous or named functions:

function myFunc() {
    this.myMethod = () => {
        //..
    }
}

function myFunc() {
    this.myMethod = function() {
        //..
    }
}

Taken from MDN:

An arrow function expression has a shorter syntax compared to function expressions and does not bind its own this, arguments, super, or new.target. Arrow functions are always anonymous. These function expressions are best suited for non-method functions and they can not be used as constructors.

It makes sense to us anonymous as you might want to access myFunc properties without having to do _this = this. On the other hand it states anonymous functions are best suited for non-method functions (i.e. callbacks).

basickarl
  • 25,903
  • 43
  • 172
  • 270
  • 3
    Both your `myMethod` functions are anonymous expressions? – Bergi Nov 23 '16 at 09:56
  • ^ Right, as the MDN says using the arrow syntax saves you from hassle of referencing this to another variable to use it later. Non-arrow functions are from ES5 syntax, so if you are using ES6 always use arrow functions, it is not going to break anything but it'll help you at referencing `this`. – Diabolic Nov 23 '16 at 10:44
  • @Diabolic _"if you are using ES6 always use arrow functions, it is not going to break anything"_ That's not correct. If a callback is invoked with a defined `this` value, then an arrow function will have the "wrong" value for `this`. – a better oliver Nov 23 '16 at 11:45
  • See also: [Arrow function vs function declaration / expressions: Are they equivalent / exchangeable?](http://stackoverflow.com/q/34361379/218196) – Felix Kling Nov 23 '16 at 15:50

2 Answers2

1

Those are not contradictory.

It makes sense to use anonymous arrow functions as you might want to access myFunc instance properties without having to do _this = this.

Yes. Though if it was a method, you could simply use this within the function expression and it would work.

On the other hand it states anonymous functions function expressions are best suited for non-method functions (i.e. callbacks).

The "non-method" refers to functions that are not (always) invoked using the object.method(…) pattern that does set the this keyword. It does not matter whether the function is stored as an object property or not.

Btw, none of these points have anything to do with named vs anonymous expressions.

Bergi
  • 513,640
  • 108
  • 821
  • 1,164
0

Technically - it doesn't matter.

var myFunction = function() { } //anonymous

and

var myFunction = function myFunction() { } //named

Will be identical in all regards but one - using debug tools and looking at stack traces will show different identifiers. The first version will show up as (anonymous function) while the latter will show up with its name - myFunction. So, named functions are purely for developer convenience and for development.

Worth noting that the name of the function does not need to be the same as the reference to it, for example you can have

var myFunction = function someOtherName() { /* ... */ }

and then this will show up as someOtherName in dev tools. However you will not be able to call it by doing someOtherName() - the name and the reference to the function are different things. For simplicity they are usually set to the same identifier.

Now, onto your example - there is a difference to what you posted

function myFunc() {
    this.myMethod = () => {
        //..
    }
}

This is not equivalent to a named function. This is using the ES6 arrow functions - normally, they will be named the same as the variable they are assigned to:

var arrowFunction = () => {};

var obj = {
  arrowMethod: () => {}
}

console.log("function name is: " + arrowFunction.name);
console.log("object property function name is: "+ obj.arrowMethod.name);

(note that this works in Chrome but not in Firefox for some reason - the .name property is supposed to be set)

Further to the naming differences, arrow functions have other differences to a "plain" function. Most notably, their context is lexically bound. Here is what this means in practice

function arrowExample() {
    this.data = "Hello arrow";
    this.myMethod = () => {
        return this.data;
    }
}

function normalFunctionExample() {
    this.data = "Hello normal function";
    this.myMethod = function myMethod() {
        return this.data;
    }
}

var arrowInstance = new arrowExample();
var normalFunctionExampleInstance = new normalFunctionExample();

console.log("Invoking arrow with context: " + arrowInstance.myMethod());
console.log("Invoking normal function with context: " + normalFunctionExampleInstance.myMethod());

var arrowReference = arrowInstance.myMethod;
var normalFunctionReference = normalFunctionExampleInstance.myMethod;

console.log("Invoking arrow without context: " + arrowReference());
console.log("Invoking normal function without context: " + normalFunctionReference());
VLAZ
  • 18,437
  • 8
  • 35
  • 54