1

I'm learning Destructuring Assignment in JS and encountered this code which I don't understand.
Isn’t half a variable, why could we use it as a function and pass an argument in console.log?
What would it look like if we write the same code in a basic way?
Thank you!

const stats = {
 max: 56.78,
 min: -0.75
};

const half = ({max,min}) => (max+min)/2.0;

console.log(half(stats));

const stats = {
  max: 56.78,
  min: -0.75
};

const half = ({max,min}) => (max+min)/2.0;

console.log(half(stats));
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87
I am a cat
  • 23
  • 3
  • 1
    _"Can we use variable as a function?"_ - Yes. Just execute your example. – Andreas Aug 22 '22 at 11:33
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Functions – Simon Aug 22 '22 at 11:34
  • 2
    The variable `half` holds a reference to the function `({max,min}) => (max+min)/2.0`... So you can call it. It's that simple. You can rewrite this by using `function` syntax – casraf Aug 22 '22 at 11:34
  • I've added a snippet of your code ... click run ... you won't believe what happens next (sorry, reading too much clickbait lately) – Jaromanda X Aug 22 '22 at 11:37
  • `half` is something called function expression. Second, you are not passing function as argument. You can but in this case, you are calling the function and passing its result to `console.log`. Refer this: https://medium.com/@mandeep1012/function-declarations-vs-function-expressions-b43646042052 – Rajesh Aug 22 '22 at 11:41
  • One advantage of the `const` version is that it forces the function to be block scoped, rather than function scoped, this could prevent some strange errors.. :) – Keith Aug 22 '22 at 11:43

6 Answers6

5

JavaScript allows you to use function definition and function assignment.

function myFunction() {}

On top of this, you can also assign your function to another variable (like an alias)

const myAlias = myFunction

You can also define this all in one line

const myAlias = function myFunction() {}

Since you would like to re-assign / rename your function, you can define an anonymous function (omit the function name) and assign it to a variable

const myAlias = () => {}
marcobiedermann
  • 4,317
  • 3
  • 24
  • 37
2

First of all, in JavaScript functions are Objects that implement the [[runnable]] interface. As with any other object, this can be assigned to a variable, passed around as an argument to other functions etc. The latter is commonly referred to as JavaScript functions being first-class citizens:

In programming language design, a first-class citizen [...] in a given programming language is an entity which supports all the operations generally available to other entities. These operations typically include being passed as an argument, returned from a function, and assigned to a variable.

JavaScript has the concept of named functions, but this feature is not available for ES6 "arrow" functions (as the one you're showing).

Hence the only way to give such an anonymous arrow function a name (and thus, make it available for calling later) is to assign (always) anonymous arrow functions to a variable, which then acts as a pointer to that anonymous function.

That is exactly what is happening in your line

const half          = ({max,min}) => (max+min)/2.0;
//    ^^^ variable    ^^^ anonymous arrow function

Also note that only arrow functions allow to omit the return keyword and the {} block markers around it, if all that follows is a single expression.

With "old" ES5 functions, you could outright declare a named function:

const stats = {
  max: 56.78,
  min: -0.75
};

console.log(half(stats));

// ES 5 function declarations are "hoisted"
// meaning you can call them in your code before
// declaring the function
function half({max,min}) { 
  return (max+min)/2; 
}

Please also note that compared to your code, there are minor additional technical differences. Named ES5 function declarations are hoisted, which means the JS interpreter pulls them right to the top of your code, making the function available for calling even before declaring it.

connexo
  • 53,704
  • 14
  • 91
  • 128
0

Yes, you can store functions as variables in JS.

// Arrow style
const myFunction = () => { console.log('hi!') };

// 'Function' keyword style
const anotherFunction = function() { console.log('hi!') };

Take in consideration this is going to work differently than a common function based on the code placement due to hositing. var functionName = function() {} vs function functionName() {}

Luka Cerrutti
  • 667
  • 1
  • 4
  • 9
  • The function is not a "variable" and OP already knows that because that's the exact same setup as in the question – Andreas Aug 22 '22 at 11:36
0

Yes. JavaScript has first-class functions. Cool, huh?

This means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures

Ben Aston
  • 53,718
  • 65
  • 205
  • 331
0

There is not a massive difference between the const and function version. So the question is why is const version becoming popular,.

I think it's mainly down to scope, a pure function declaration scope is similar to how var works, were it gets hoisted to the function scope, were const / let are block scoped. Also the arrow function () => {} assigned to a const seems to create slightly less code too.

Below is a simple example were initially they look like they might do the same thing, but you will notice the function version returns OUTER/inner/inner, but the const version does OUTER/inner/OUTER, so seems more logical..

function test1() {
  function log() {
    console.log('OUTER');
  }
  log();
  {
    function log() {
      console.log('inner');
    }
    log();
  }
  log(); 
}

function test2() {
  const log = () => console.log('OUTER');
  log();
  {
    const log = () => console.log('inner');
    log();
  }
  log(); 
}



console.log('simple function');
test1();

console.log('const function');
test2();
Keith
  • 22,005
  • 2
  • 27
  • 44
0

Sure. Javascript natively supports first class functions.

https://en.wikipedia.org/wiki/First-class_function

Therefore, that you can pass function as argument of another function, or return function as result of calculating of another function.

Also, functions can be anonymous. In your case, you creating constant variable half, and assigning arrow (anonymous) function as value ({max,min}) => (max+min)/2.0. So calling half with () operator will execute it. I'ts very common practice.

// in imperative scenario, assigning as variable allows you to tweak some behavior. But am not recommend to use this way in production, because i'ts much harder to controll app state while debugging
 
var SomeBehaviour;
SomeBehaviour = ({max,min}) => (max + min)/2.0;
SomeBehaviour();
SomeBehaviour = ({max,min}) => (max - min)/4.0;
SomeBehaviour(); 
// just common anonimous function 
[ { min: 1, max: 2 } , { min: 3, max: 4 } ].map( ({max,min}) => (max + min)/2.0 )  
// classic function
function half({max,min}) 
{
   return (max+min)/2.0
}; 

Main difference of using one of thouse scenarious would be in behaviour of this keyword in context.

Basically, if you don't use this in your module - you can don't worry. Else - i advice you to read Kyle Simpsons book "This and Object prorotypes"