unexposed

    1.0.0 • Public • Published

    unexposed

    npm install
    Travis Build Status CircleCI Build Status Build Status CircleCI Dependencies Status Known Vulnerabilities Downloads License

    This module exposes the unexposed: AsyncFunction, GeneratorFunction, Generator

    TL;DR

    Before:

    > x = function () {};
    [Function: x]
    > x instanceof Function;
    true
    > x = async function () {};
    [AsyncFunction: x]
    > x instanceof AsyncFunction;
    ReferenceError: AsyncFunction is not defined

    After:

    > x = function () {};
    [Function: x]
    > x instanceof Function;
    true
    > x = async function () {};
    [AsyncFunction: x]
    > x instanceof AsyncFunction;
    true

    Intro

    JavaScript has some global objects that are not really exposed as global objects. I call them unexposed objects:

    > x = function () {};
    [Function: x]
    > x instanceof Function;
    true
    > x = async function () {};
    [AsyncFunction: x]
    > x instanceof AsyncFunction;
    ReferenceError: AsyncFunction is not defined

    The purpose of this module is to expose the unexposed. What you do with them is up to you.

    The question whether it is smart to use them or they should remain unexposed for eternity is beyond the scope of this documentation.

    Installation

    To install in a project:

    npm install unexposed

    Usage

    Using local variables:

    const { AsyncFunction } = require('unexposed');

    Adding global variables:

    require('unexposed').addGlobals();

    or:

    require('unexposed')();

    Note that it may not be a good idea to add global variables in production code but it may be useful in REPL or for some experiments.

    Returned Objects

    Currently this modules exposes:

    • AsyncFunction
    • GeneratorFunction
    • Generator

    Rationale

    JavaScript has some global objects that are not really exposed as global objects. They are usually documented under "global objects" in documentation like MDN, anyway, because it's hard to classify them otherwise.

    For example, we have Function in JS Reference / Global Objects:

    that explains what new Function() does.

    We also have AsyncFunction in the same JS Reference / Global Objects:

    that explains what new AsyncFunction() does, but it also contains an interesting note:

    "Note that AsyncFunction is not a global object."

    In the Node REPL we can create a function and inspect it:

    > x = function () {};
    [Function: x]
    > Function
    [Function: Function]

    but it we do the same with an async function then we get a strange error:

    > x = async function () {};
    [AsyncFunction: x]
    > AsyncFunction
    ReferenceError: AsyncFunction is not defined

    We can easily instantiate Function with:

    = new Function();

    But how can we use new AsyncFunction() syntax that is explained in the documentation if AsyncFunction is not defined? We need to use hacks like this:

    = new (Object.getPrototypeOf(async function () {}).constructor)();

    which is unreadable and error prone.

    Generators

    For some context, see:

    Especially Figure 2 — Generator Objects Relationships:

    Figure 2 — Generator Objects Relationships

    Both of those hold true:

    (function* () {}).constructor.prototype === (function* () {} ()).constructor;
    Object.getPrototypeOf(function* () {}).constructor.prototype === Object.getPrototypeOf(function* () {} ()).constructor;

    And also:

    (function* () {}).constructor === Object.getPrototypeOf(function* () {}).constructor;
    (function* () {} ()).constructor === Object.getPrototypeOf(function* () {} ()).constructor;

    But at the same time:

    typeof (function* () {}).constructor === 'function';
    typeof (function* () {} ()).constructor === 'object';

    which means that the constructor of a generator is not a function and unlike the constructor of a generator function, you cannot really use this constructor as a constructor!

    This is fine:

    > new (function* () {}).constructor();
    [GeneratorFunction: anonymous]

    but this is an error:

    > new (function* () {} ()).constructor();
    TypeError: (intermediate value)(...).constructor is not a constructor

    Yes, constructor is not a constructor.

    Issues

    For any bug reports or feature requests please post an issue on GitHub.

    Author

    Rafał Pocztarski
    Follow on GitHub Follow on Twitter
    Follow on Stack Exchange

    License

    MIT License (Expat). See LICENSE.md for details.

    Install

    npm i unexposed

    DownloadsWeekly Downloads

    9

    Version

    1.0.0

    License

    MIT

    Unpacked Size

    16.4 kB

    Total Files

    15

    Last publish

    Collaborators

    • avatar