Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to programmatically distinguish an arrow function from a regular function?

Tags:

javascript

There is no obvious difference between an arrow function and a regular function.

({}).toString.call(function () {})
"[object Function]"
({}).toString.call(() => {})
"[object Function]"

or

console.dir( (function () {}) )
function anonymous()
    arguments: null
    caller: null
    length: 0
    name: ""
    prototype: Object
    __proto__: ()
    <function scope>
console.dir( (() => {}) )
function anonymous()
    arguments: (...)
    caller: (...)
    length: 0
    name: ""
    __proto__: ()
    <function scope>

The behaviour of the two is different though and there is a valid use case for being able to tell the two apart.

How to programmatically distinguish an arrow function from a regular function?

like image 578
Gajus Avatar asked Dec 12 '15 19:12

Gajus


People also ask

What are the two main differences in arrow functions?

There are differences between arrow functions and traditional functions, as well as some limitations: Arrow functions don't have their own bindings to this , arguments or super , and should not be used as methods. Arrow functions don't have access to the new.target keyword.

What technical advantages of using arrow functions over normal functions apart from syntax?

Main benefit: No binding of 'this' In classic function expressions, the this keyword is bound to different values based on the context in which it is called. With arrow functions however, this is lexically bound. It means that it uses this from the code that contains the arrow function.

How are arrow functions different from regular functions?

Since regular functions are constructible, they can be called using the new keyword. However, the arrow functions are only callable and not constructible, i.e arrow functions can never be used as constructor functions. Hence, they can never be invoked with the new keyword.

Why arrow function are better than normal function in JavaScript?

let add = (x, y) => { return x + y }; JavaScript arrow functions are roughly the equivalent of lambda functions in python or blocks in Ruby, but they have more intricate details. Arrow functions allow a developer to accomplish the same result with fewer lines of code and approximately half the typing.


2 Answers

The best I can think of is using toString:

let isArrowFunction;

isArrowFunction = (fn) => {
    console.log(fn.toString());

    return fn.toString().indexOf('function') !== 0;
};

console.log(isArrowFunction(() => {}) === true);
console.log(isArrowFunction((foo: string) => {}) === true);
console.log(isArrowFunction(function () {}) === false);

See:

(function () {}).toString();
"function () {}"

(() => {}).toString();
"() => {}"
like image 101
Gajus Avatar answered Sep 19 '22 11:09

Gajus


Uhm, the requirements are a bit weird, but I made some tests and:

typeof (() => {}).prototype === "undefined"

Is true, while:

typeof (function () {}).prototype === "undefined"

Is false, so:

function isArrow(x)
{
  return typeof (x.prototype) === "undefined"
}

Fiddle here: https://jsfiddle.net/87kn67ov/

like image 37
Jcl Avatar answered Sep 20 '22 11:09

Jcl